<template>
  <div v-if="userStore.loading && !userStore.user" class="loading-container d-flex justify-content-center align-items-center" style="min-height: 50vh;">
    <div class="spinner-border text-primary" role="status">
      <span class="visually-hidden">Loading...</span>
    </div>
  </div>

  <div v-else-if="!userStore.isLoggedIn" class="login-redirect-container mt-5">
    <center><h3 style="padding:10px;">Please Login</h3></center>
     <Login />
  </div>
  <div v-else class="account-settings-page">
    <br><br><br>
    
    <div class="mt-1">
      <div class="tf-container">
        <CardSimple class="mb-4">
          <div class="inner d-flex flex-column align-items-center justify-content-center py-3">
            <div class="box-avatar" @click="viewFullScreen" style="position: relative; cursor: pointer;">
              <img :src="displayPhotoUrl" id="account_settings_profile_picture" alt="image" style="object-fit: cover;">
              <div class="camera-edit-badge" @click.stop="triggerFilePicker">
                <i class="fas fa-camera"></i>
              </div>
              <input type="file" ref="fileInput" @change="onFileSelected" accept="image/*" style="display: none;">
            </div>
            <div class="info text-center">
              <h2 class="fw_8 mt-3 mb-1" style="color: var(--text-primary);">{{ userStore.fullName }}</h2>
              <p class="text-muted small">@{{ userStore.user?.username }}</p>
            </div>
          </div>

          <!-- Balance Card -->
          <div class="balance-summary-card mx-3 mb-3 p-3 rounded-20 bg-primary text-white d-flex justify-content-between align-items-center shadow-sm" @click="navigate({ page: 'MyWallet' })" style="cursor: pointer;">
              <div>
                  <p class="smallest fw_6 mb-0 text-white-50">Current Balance</p>
                  <h3 class="fw_8 mb-0">₱{{ userStore.user?.total_balance || 0 }}</h3>
              </div>
              <div class="bg-white-20 rounded-circle p-2">
                  <i class="fas fa-chevron-right text-white"></i>
              </div>
          </div>
          
          <ul class="list-user-info-container mt-4 mb-0 list-unstyled">
            <li class="list-user-info d-flex align-items-center p-3">
              <i class="fas fa-user-circle me-3 text-primary"></i>
              <h5 class="mb-0">{{ userStore.fullName }}</h5>
            </li>
            <li v-if="userStore.mobileNumber" class="list-user-info d-flex align-items-center p-3">
              <i class="fas fa-mobile-alt me-3 text-primary"></i>
              <h5 class="mb-0">{{ userStore.mobileNumber }}</h5>
            </li>
            <li v-if="userStore.email" class="list-user-info d-flex align-items-center p-3">
              <i class="fas fa-envelope me-3 text-primary"></i>
              <h5 class="mb-0">{{ userStore.email }}</h5>
            </li>
            <li class="list-user-info border-none d-flex align-items-center p-3">
              <i class="fas fa-id-badge me-3 text-primary"></i>
              <h5 class="mb-0">Account Type: {{ accountTypeName }}</h5>
            </li>
          </ul>
        </CardSimple>
      </div>
    </div>

        <div class="tf-container">
          <CardSimple title="Settings & Tools">
            <ul class="box-service mt-3">
              <li>
                <a href="javascript:void(0);" @click="toggleDarkMode">
                  <div class="icon-box" style="background: var(--accent-soft); border-radius: 12px;">
                    <i :class="uiStore.darkMode ? 'fas fa-sun' : 'fas fa-moon'" style="font-size: 24px; color: #533dea;"></i>
                  </div>
                  <span class="mt-2" style="font-size: 13px; font-weight: 600;">{{ uiStore.darkMode ? 'Light' : 'Dark' }}</span>
                </a>
              </li>
              <li>
                <a href="javascript:void(0);" @click="openChangePasswordModal">
                  <div class="icon-box" style="background: var(--accent-soft); border-radius: 12px;">
                    <i class="fas fa-key" style="font-size: 24px; color: var(--accent-color);"></i>
                  </div>
                  <span class="mt-2" style="font-size: 13px; font-weight: 600;">Password</span>
                </a>
              </li>
              <li>
                <a href="javascript:void(0);" @click="clearCacheAndReload">
                  <div class="icon-box" style="background: rgba(57, 163, 248, 0.15); border-radius: 12px;">
                    <i class="fas fa-sync" style="font-size: 24px; color: #39a3f8;"></i>
                  </div>
                  <span class="mt-2" style="font-size: 13px; font-weight: 600;">Reset App</span>
                </a>
              </li>
              <li>
                <a href="javascript:void(0);" @click="showNotes">
                  <div class="icon-box" style="background: rgba(242, 195, 28, 0.15); border-radius: 12px;">
                    <i class="fas fa-sticky-note" style="font-size: 24px; color: #f2c71c;"></i>
                  </div>
                  <span class="mt-2" style="font-size: 13px; font-weight: 600;">Notes</span>
                </a>
              </li>
              <li>
                <a href="javascript:void(0);" @click="openTransferBalanceModal">
                  <div class="icon-box" style="background: rgba(40, 199, 111, 0.15); border-radius: 12px;">
                    <i class="fas fa-exchange-alt" style="font-size: 24px; color: #28c76f;"></i>
                  </div>
                  <span class="mt-2" style="font-size: 13px; font-weight: 600;">Transfer</span>
                </a>
              </li>
              <li>
                <a href="javascript:void(0);" @click="navigate({ page: 'MyWallet' })">
                  <div class="icon-box" style="background: rgba(30, 64, 175, 0.15); border-radius: 12px;">
                    <i class="fas fa-wallet" style="font-size: 24px; color: #1e40af;"></i>
                  </div>
                  <span class="mt-2" style="font-size: 13px; font-weight: 600;">My Wallet</span>
                </a>
              </li>
              <li>
                <a href="javascript:void(0);" @click="showTableDensityModal">
                  <div class="icon-box" style="background: rgba(83, 61, 234, 0.15); border-radius: 12px;">
                    <i class="fas fa-bars" style="font-size: 24px; color: #533dea;"></i>
                  </div>
                  <span class="mt-2" style="font-size: 13px; font-weight: 600;">Density</span>
                </a>
              </li>
              <li>
                <a href="javascript:void(0);" @click="logout">
                  <div class="icon-box" style="background: rgba(234, 52, 52, 0.15); border-radius: 12px;">
                    <i class="fas fa-sign-out-alt" style="font-size: 24px; color: #ea3434;"></i>
                  </div>
                  <span class="mt-2" style="font-size: 13px; font-weight: 600;">Logout</span>
                </a>
              </li>
            </ul>
          </CardSimple>

          <!-- QRPH Payment Code — ULTIMATE only -->
          <CardSimple v-if="userStore.acctType === 'ult'" title="Payment QR Code (QRPH)" class="mb-4">
            <div class="p-3">
              <p class="smallest text-muted mb-3">
                Set your personal QRPH string (from GCash, Maya, or your bank's "Receive" QR) so members can scan it when topping up their wallet.
              </p>

              <!-- Current code preview -->
              <div v-if="qrphDecoded" class="d-flex align-items-center gap-2 mb-3 p-2 rounded-20" style="background:var(--bg-secondary,#f5f5f5);">
                <div class="rounded-circle d-flex align-items-center justify-content-center flex-shrink-0"
                     style="width:36px;height:36px;background:rgba(83,61,234,0.12);">
                  <i class="fas fa-university" style="color:#533dea;font-size:14px;"></i>
                </div>
                <div class="flex-grow-1 text-start overflow-hidden">
                  <p class="mb-0 fw_7 text-truncate" style="font-size:13px;">{{ qrphDecoded.merchant_name || 'Merchant' }}</p>
                  <p class="mb-0 text-muted" style="font-size:11px;">
                    {{ qrphDecoded.merchant_account?.network || '' }}
                    <span v-if="qrphDecoded.merchant_account?.account"> · {{ qrphDecoded.merchant_account.account }}</span>
                    <span v-if="!qrphDecoded.valid" class="text-warning ms-1"><i class="fas fa-exclamation-triangle"></i> CRC mismatch</span>
                    <span v-else class="text-success ms-1"><i class="fas fa-check-circle"></i> Valid</span>
                  </p>
                </div>
                <button @click="openQrphModal" class="btn btn-sm btn-outline-primary rounded-pill smallest fw_6 flex-shrink-0">
                  Update
                </button>
              </div>

              <button v-else @click="openQrphModal" class="btn btn-primary rounded-pill w-100 py-2 fw_7 d-flex align-items-center justify-content-center gap-2">
                <i class="fas fa-qrcode"></i> Set QRPH Code
              </button>
            </div>
          </CardSimple>

          <div class="text-center mt-5 mb-2">
              <p class="mb-0" style="font-size: 10px; color: #a0a0a0; font-weight: 700; letter-spacing: 0.8px; text-transform: uppercase; opacity: 0.6;">
                {{ uiStore.appName }}
              </p>
              <p class="mb-0" style="font-size: 11px; color: #533dea; font-weight: 600; opacity: 0.8;">
                Version v{{ appVersion }} (Build {{ buildId }})
              </p>
          </div>
        </div>
      <br><br>
    </div>
  </template>

<script>
import { defineComponent, computed, h, ref, onMounted } from 'vue';
import { useAuth } from '../composables/Core/useAuth.js';
import { useModal } from '../composables/Core/useModal.js';
import { useNavigate } from '../composables/Core/useNavigate.js';
import axios from 'axios';
import Login from './Auth/Login.vue';
import { usePageTitle } from '../composables/Core/usePageTitle';
import { useUserNotes } from '../composables/useUserNotes';
import { useUIStore } from '../stores/ui.js';
import { useUserSettings } from '../composables/useUserSettings.js';
import TableDensityToggle from '../Components/Core/TableDensityToggle.vue';
import CardSimple from '../Components/Core/CardSimple.vue';
import InputGroupButton from '../Components/Core/Forms/InputGroupButton.vue';
import { getUserTypeLabel } from '../utils/userTypeLabels.js';

export default defineComponent({
  name: 'AccountSettings',
  components: {
    Login
  },
  setup() {
    const { user, isPublic, userStore } = useAuth();
    const { fetchNotes, dismissNotes, notes, loading, error } = useUserNotes();
    usePageTitle('Account Settings');
    const modal = useModal();
    const { navigate } = useNavigate();
    const uiStore = useUIStore();
    const { settings, updateSetting } = useUserSettings();
    const fileInput = ref(null);
    const isUpdatingPhoto = ref(false);
    const photoCacheBust = ref(Date.now());

    const displayPhotoUrl = computed(() => {
      const url = userStore.photoUrl;
      // If it's the placeholder from UI Avatars, return as-is
      if (url.includes('ui-avatars.com')) return url;
      
      // Add cache busting for real photos
      const separator = url.includes('?') ? '&' : '?';
      return `${url}${separator}t=${photoCacheBust.value}`;
    });

    const triggerFilePicker = () => {
      fileInput.value.click();
    };

    const viewFullScreen = () => {
      modal.open({
        title: false,
        body: h('div', { 
          class: 'full-screen-image-container d-flex justify-content-center align-items-center',
          style: 'min-height: 50vh; background: #000; border-radius: 20px; overflow: hidden; position: relative; padding: 10px;'
        }, [
          h('img', {
            src: displayPhotoUrl.value,
            style: 'max-width: 100%; max-height: 80vh; object-fit: contain; border-radius: 12px;'
          }),
          h('button', {
            class: 'btn-close btn-close-white',
            style: 'position: absolute; top: 15px; right: 15px; z-index: 10; background-color: rgba(255,255,255,0.2); padding: 12px; border-radius: 50%; border: none; font-size: 20px; line-height: 1; color: white;',
            onClick: modal.close
          }, '×')
        ]),
        footer: null
      });
    };

    const onFileSelected = async (event) => {
      const file = event.target.files[0];
      if (!file) return;

      // Validate file type
      if (!file.type.startsWith('image/')) {
        modal.open({
          title: 'Invalid File',
          body: 'Please select an image file.',
          footer: h('button', { class: 'btn btn-secondary', onClick: modal.close }, 'Close')
        });
        return;
      }

      // Validate file size (e.g., 5MB)
      if (file.size > 5 * 1024 * 1024) {
        modal.open({
          title: 'File Too Large',
          body: 'Image size should be less than 5MB.',
          footer: h('button', { class: 'btn btn-secondary', onClick: modal.close }, 'Close')
        });
        return;
      }

      const formData = new FormData();
      formData.append('photo', file);

      try {
        isUpdatingPhoto.value = true;
        modal.open({
          title: 'Updating Photo',
          body: h('div', { class: 'text-center py-4' }, [
            h('div', { class: 'spinner-border text-primary', role: 'status' }),
            h('p', { class: 'mt-2' }, 'Uploading your new photo...')
          ])
        });

        const response = await axios.post('/user/updatephoto', formData, {
          headers: {
            'Content-Type': 'multipart/form-data'
          }
        });

        if (response.data && response.data.success) {
          modal.open({
            title: 'Success',
            body: 'Profile photo updated successfully.',
            footer: h('button', { 
              class: 'btn btn-primary', 
              onClick: () => {
                modal.close();
                
                // Refresh full user data in background
                userStore.fetchCurrentUser().then(() => {
                    // Force UI update with cache bust again after fetch
                    photoCacheBust.value = Date.now();
                });
              } 
            }, 'OK')
          });
        } else {
          modal.open({
            title: 'Failed',
            body: 'Failed to update profile photo: ' + (response.data.message || 'Unknown error'),
            footer: h('button', { class: 'btn btn-secondary', onClick: modal.close }, 'Close')
          });
        }
      } catch (error) {
        modal.open({
          title: 'Error',
          body: 'An error occurred while uploading the photo: ' + (error.response?.data?.message || error.message),
          footer: h('button', { class: 'btn btn-secondary', onClick: modal.close }, 'Close')
        });
      } finally {
        isUpdatingPhoto.value = false;
      }
    };
    
    // For password change binding
    const oldPassword = ref('');
    const newPassword = ref('');
    const newPasswordConfirm = ref('');
    const isChangingPassword = ref(false);
    const passwordError = ref('');

    const openChangePasswordModal = () => {
      oldPassword.value = '';
      newPassword.value = '';
      newPasswordConfirm.value = '';
      passwordError.value = '';
      
      const ChangePasswordForm = {
        setup() {
          return () => h('div', { class: 'change-password-modal-body' }, [
            passwordError.value ? h('div', { class: 'alert alert-error mb-3' }, passwordError.value) : null,
            
            h('div', { class: 'form-group mb-3' }, [
              h('div', { class: 'input-group' }, [
                h('div', { class: 'input-group-prepend' }, [
                  h('span', { class: 'input-group-text' }, [
                    h('i', { class: 'icon-secure1', style: 'font-size: 20px; color: #533dea;' })
                  ])
                ]),
                h('input', {
                  type: 'password',
                  class: 'form-control',
                  placeholder: 'Current Password',
                  style: 'height: 50px; border-left: none;',
                  value: oldPassword.value,
                  onInput: e => oldPassword.value = e.target.value
                })
              ])
            ]),

            h('div', { class: 'form-group mb-3' }, [
              h('div', { class: 'input-group' }, [
                h('div', { class: 'input-group-prepend' }, [
                  h('span', { class: 'input-group-text' }, [
                    h('i', { class: 'icon-secure1', style: 'font-size: 20px; color: #533dea;' })
                  ])
                ]),
                h('input', {
                  type: 'password',
                  class: 'form-control',
                  placeholder: 'New Password',
                  style: 'height: 50px; border-left: none;',
                  value: newPassword.value,
                  onInput: e => newPassword.value = e.target.value
                })
              ])
            ]),

            h('div', { class: 'form-group mb-3' }, [
              h('div', { class: 'input-group' }, [
                h('div', { class: 'input-group-prepend' }, [
                  h('span', { class: 'input-group-text' }, [
                    h('i', { class: 'icon-secure1', style: 'font-size: 20px; color: #533dea;' })
                  ])
                ]),
                h('input', {
                  type: 'password',
                  class: 'form-control',
                  placeholder: 'Confirm Password',
                  style: 'height: 50px; border-left: none;',
                  value: newPasswordConfirm.value,
                  onInput: e => newPasswordConfirm.value = e.target.value
                })
              ])
            ])
          ]);
        }
      };

      modal.yesNoModal({
        title: 'Change Password',
        body: h(ChangePasswordForm),
        yesText: 'Change Password',
        noText: 'Close',
        onYes: () => {
          submitChangePassword();
        }
      });
    };

    const submitChangePassword = async () => {
      if (!oldPassword.value || newPassword.value.length < 6 || newPassword.value !== newPasswordConfirm.value) {
        modal.open({
          title: 'Error',
          body: 'Invalid password inputs. Password must be at least 6 characters and match.',
          footer: h('button', { class: 'btn btn-secondary', onClick: modal.close }, 'Close')
        });
        return;
      }
      
      try {
        isChangingPassword.value = true;
        const response = await axios.post('/user/changemypassword', {
          current_password: oldPassword.value,
          new_password: newPassword.value,
          new_confirm_password: newPasswordConfirm.value
        });
        
        if (response.data === true || (typeof response.data === 'string' && response.data.includes('Password changed successfully'))) {
          modal.open({
            title: 'Success',
            body: 'Password has been changed successfully. You will be logged out.',
            footer: h('button', {
              class: 'btn btn-primary',
              onClick: () => {
                modal.close();
                window.location.href = '/go/logoutnow';
              }
            }, 'OK')
          });
        } else {
          modal.open({
            title: 'Failed',
            body: 'Unable to change password. ' + JSON.stringify(response.data),
            footer: h('button', { class: 'btn btn-secondary', onClick: modal.close }, 'Close')
          });
        }
      } catch (error) {
        modal.open({
          title: 'Failed',
          body: 'An error occurred while changing your password. ' + (error.response?.data?.message || ''),
          footer: h('button', { class: 'btn btn-secondary', onClick: modal.close }, 'Close')
        });
      } finally {
        isChangingPassword.value = false;
      }
    };

    const clearCacheAndReload = () => {
      if (typeof window.clearCacheAndReload === 'function') {
        window.clearCacheAndReload();
      } else {
        localStorage.clear();
        sessionStorage.clear();
        window.location.reload(true);
      }
    };

    const showNotes = async () => {
      // Fetch notes using composable
      await fetchNotes();
      
      if (error.value) {
        modal.open({
          title: 'Error',
          body: error.value,
          footer: h('button', { class: 'btn btn-secondary', onClick: modal.close }, 'Close')
        });
        return;
      }
      
      const notesContent = notes.value;
      
      if (notesContent && notesContent.trim() !== '') {
        modal.continueCancelModal({
          title: 'Notes',
          body: h('div', { 
              style: 'white-space: pre-wrap; font-size: 16px; line-height: 1.5; color: #333;' 
          }, notesContent),
          continueText: 'Delete Note',
          cancelText: 'Close',
          continueClass: 'btn btn-danger',
          cancelClass: 'btn btn-secondary',
          onContinue: async () => {
            const success = await dismissNotes();
            if (success) {
              // Refresh notes after dismissal
              await fetchNotes();
            }
          }
        });
      } else {
        modal.open({
          title: 'No Notes',
          body: h('div', { class: 'text-center py-3' }, [
              h('i', { class: 'icon-copy2 mb-3', style: 'font-size: 48px; color: #ccc; display: block;' }),
              h('p', { style: 'font-size: 16px; color: #717171;' }, 'No notes found.')
          ]),
          footer: h('button', { 
              class: 'btn btn-primary w-100', 
              style: 'height: 52px; border-radius: 16px; font-weight: 700;',
              onClick: modal.close 
          }, 'OK')
        });
      }
    };

    const logout = () => {
      if (typeof window.clearCacheAndLogout === 'function') {
        window.clearCacheAndLogout();
      } else {
        localStorage.clear();
        sessionStorage.clear();
        window.location.href = '/go/logoutnow';
      }
    };

    const toggleDarkMode = async () => {
      const newMode = !uiStore.darkMode;
      uiStore.setDarkMode(newMode);
      
      try {
        await axios.post('/UserSettings/Update', {
          dark_mode: newMode
        });
      } catch (error) {
        console.error('Failed to update dark mode setting on server:', error);
      }
    };

    const showTableDensityModal = () => {
      const density = ref(settings.value.table_density || 'comfortable');
      
      const DensityWrapper = {
        setup() {
          return () => h('div', { class: 'text-center py-3' }, [
            h('p', { class: 'mb-4 text-muted' }, 'Choose how dense you want your data tables to appear.'),
            h('div', { class: 'd-flex justify-content-center' }, [
              h(TableDensityToggle, {
                modelValue: density.value,
                'onUpdate:modelValue': (val) => {
                  density.value = val;
                  updateSetting('table_density', val);
                }
              })
            ]),
            h('div', { class: 'mt-4 p-3 rounded-3 bg-light text-start' }, [
              h('div', { class: 'small fw_6 mb-1 text-dark' }, 'Preview:'),
              h('div', { 
                class: 'density-table-preview border rounded overflow-hidden',
                'data-table-density': density.value
              }, [
                h('table', { class: 'table table-sm density-table mb-0' }, [
                  h('tr', [h('td', 'Sample Row 1'), h('td', '₱1,000.00')]),
                  h('tr', [h('td', 'Sample Row 2'), h('td', '₱2,500.00')])
                ])
              ])
            ])
          ]);
        }
      };

      modal.open({
        title: 'Table Density',
        body: h(DensityWrapper),
        footer: h('button', { 
          class: 'btn btn-primary w-100', 
          onClick: modal.close 
        }, 'Done')
      });
    };

    // Balance Transfer Logic
    const descendants = ref([]);
    const isLoadingDescendants = ref(false);

    const fetchDescendants = async () => {
      try {
        isLoadingDescendants.value = true;
        const response = await axios.get('/admin/users/list');
        if (response.data && response.data.users) {
          // Filter out the current user from the descendants list
          descendants.value = response.data.users.filter(u => u.hashkey !== userStore.user?.hashkey);
        }
      } catch (err) {
        console.error('Failed to fetch descendants', err);
      } finally {
        isLoadingDescendants.value = false;
      }
    };

    const openTransferBalanceModal = async () => {
      modal.open({
        title: 'Please Wait',
        body: h('div', { class: 'text-center py-4' }, [
          h('div', { class: 'spinner-border text-primary', role: 'status' }),
          h('p', { class: 'mt-2' }, 'Loading your children list...')
        ])
      });

      await fetchDescendants();
      
      if (descendants.value.length === 0) {
          modal.open({
            title: 'Notice',
            body: h('div', { class: 'text-center py-3' }, [
              h('i', { class: 'icon-user mb-3', style: 'font-size: 48px; color: #ccc; display: block;' }),
              h('p', { style: 'font-size: 16px; color: #717171;' }, 'You do not have any child accounts to transfer points to.')
            ]),
            footer: h('button', { 
                class: 'btn btn-primary w-100', 
                style: 'height: 52px; border-radius: 16px; font-weight: 700;',
                onClick: modal.close 
            }, 'OK')
          });
          return;
      }

      const selectedUserHash = ref('');
      const transferAmount = ref('');
      const isSending = ref(false);

      const TransferForm = {
        setup() {
          return () => h('div', { class: 'transfer-balance-modal-body' }, [
            h('div', { class: 'form-group mb-4' }, [
              h('label', { class: 'mb-2 fw_6', style: 'font-size: 14px; color: #666;' }, 'Select Recipient'),
              h('div', { class: 'input-group shadow-sm', style: 'border-radius: 16px; overflow: hidden;' }, [
                h('span', { class: 'input-group-text border-0 bg-white px-3' }, [
                  h('i', { class: 'icon-user', style: 'font-size: 20px; color: #28c76f;' })
                ]),
                h('select', {
                  class: 'form-control border-0 py-3',
                  style: 'font-size: 16px; font-weight: 500;',
                  value: selectedUserHash.value,
                  onChange: e => selectedUserHash.value = e.target.value
                }, [
                  h('option', { value: '' }, 'Choose a child...'),
                  ...(descendants.value.map(u => h('option', { value: u.hashkey }, `${u.fullname || u.username} (@${u.username}) - Bal: ${u.total_balance}`)))
                ])
              ])
            ]),
            h('div', { class: 'form-group mb-4' }, [
              h('label', { class: 'mb-2 fw_6', style: 'font-size: 14px; color: #666;' }, 'Amount to Transfer'),
              h('div', { class: 'input-group shadow-sm', style: 'border-radius: 16px; overflow: hidden;' }, [
                h('span', { class: 'input-group-text border-0 bg-white px-3' }, [
                  h('i', { class: 'icon-credit-card2', style: 'font-size: 20px; color: #28c76f;' })
                ]),
                h('input', {
                  type: 'number',
                  class: 'form-control border-0 py-3',
                  placeholder: '0.00',
                  style: 'font-size: 16px; font-weight: 600;',
                  value: transferAmount.value,
                  onInput: e => transferAmount.value = e.target.value
                })
              ])
            ]),
            h('div', { 
                class: 'p-3 rounded-4 d-flex justify-content-between align-items-center', 
                style: 'background: rgba(40, 199, 111, 0.05);' 
            }, [
                h('span', { style: 'color: #666; font-size: 14px;' }, 'Your Current Balance:'),
                h('span', { style: 'color: #28c76f; font-weight: 800; font-size: 18px;' }, userStore.user?.total_balance || 0)
            ])
          ]);
        }
      };

      modal.yesNoModal({
        title: 'Transfer Points',
        body: h(TransferForm),
        yesText: 'Confirm Transfer',
        noText: 'Cancel',
        yesClass: 'btn btn-primary w-50 py-2 rounded-3 shadow-sm fw-bold',
        onYes: async () => {
          if (!selectedUserHash.value) {
            modal.quickDismiss({ title: 'Error', body: 'Please select a recipient.' });
            return;
          }
          if (!transferAmount.value || isNaN(transferAmount.value) || parseFloat(transferAmount.value) <= 0) {
            modal.quickDismiss({ title: 'Error', body: 'Please enter a valid amount.' });
            return;
          }
          
          const amount = parseFloat(transferAmount.value);
          if (amount > (userStore.user?.total_balance || 0) && userStore.acctType !== 'ult' && userStore.acctType !== 'ultimate') {
              modal.quickDismiss({ title: 'Insufficient Balance', body: 'You do not have enough balance for this transfer.' });
              return;
          }

          try {
            modal.open({
              title: 'Please Wait',
              body: h('div', { class: 'text-center py-4' }, [
                h('div', { class: 'spinner-border text-primary', role: 'status' }),
                h('p', { class: 'mt-2' }, 'Processing transfer...')
              ])
            });

            const response = await axios.post('/user/sendmycredit', {
              target_user: selectedUserHash.value,
              amount: amount
            });
            
            if (response.data === true || response.data?.success) {
              modal.open({
                title: 'Success',
                body: h('div', { class: 'text-center py-3' }, [
                    h('i', { class: 'icon-checkmark mb-3', style: 'font-size: 48px; color: #28c76f; display: block;' }),
                    h('p', { style: 'font-size: 16px; color: #333; font-weight: 600;' }, `Successfully transferred ${amount} points.`)
                ]),
                footer: h('button', { 
                    class: 'btn btn-primary w-100', 
                    style: 'height: 52px; border-radius: 16px; font-weight: 700;',
                    onClick: modal.close 
                }, 'OK')
              });
              userStore.fetchCurrentUser(); // Refresh balance
            } else {
              modal.quickDismiss({ title: 'Error', body: response.data || 'Failed to transfer points.' });
            }
          } catch (err) {
            modal.quickDismiss({ title: 'Error', body: 'An error occurred: ' + (err.response?.data || err.message) });
          }
        }
      });
    };

    const accountTypeName = computed(() => getUserTypeLabel(userStore.acctType, uiStore.app_mode));

    // ── QRPH Management (ULTIMATE only) ────────────────────────────────────
    const qrphCode     = ref('');
    const qrphDecoded  = ref(null);
    const qrphImageUrl = ref(null);  // stored image URL from /RequestData/File/...
    // shared write-back refs from modal
    const qrphInput      = ref('');
    const qrphImgHashkey = ref('');
    const isSavingQrph   = ref(false);

    const fetchQrphCode = async () => {
      if (userStore.acctType !== 'ult') return;
      try {
        const res = await axios.post('/Financial/Qrph/Get');
        if (res.data.success && res.data.qrph) {
          qrphCode.value     = res.data.qrph;
          qrphDecoded.value  = res.data.decoded;
          qrphImageUrl.value = res.data.image_url || null;
        }
      } catch (_) {}
    };

    const saveQrph = async () => {
      isSavingQrph.value = true;
      try {
        const res = await axios.post('/Financial/Qrph/Set', {
          qrph_code:     qrphInput.value ? qrphInput.value.trim() : '',
          image_hashkey: qrphImgHashkey.value || '',
        });
        if (res.data.success) {
          qrphCode.value     = qrphInput.value ? qrphInput.value.trim() : '';
          qrphDecoded.value  = res.data.decoded || null;
          qrphImageUrl.value = res.data.image_url || null;
          if (window.toastr) window.toastr.success(res.data.message || 'QRPH code saved.');
          modal.close();
        } else {
          if (window.toastr) window.toastr.error('Failed to save QRPH code.');
        }
      } catch (_) {
        if (window.toastr) window.toastr.error('Error saving QRPH code.');
      } finally {
        isSavingQrph.value = false;
      }
    };

    const openQrphModal = () => {
      qrphInput.value      = qrphCode.value;
      qrphImgHashkey.value = '';

      const QrphForm = {
        setup() {
          const scanState       = ref(qrphCode.value ? 'done' : 'idle'); // pre-fill if already set
          const scanError       = ref('');
          const decodedRaw      = ref(qrphCode.value);
          const decodedInfo     = ref(qrphDecoded.value);
          const imagePreviewUrl = ref(qrphImageUrl.value); // show stored image on re-open
          const showManual      = ref(false);
          const isUploading     = ref(false);

          const scanAndUpload = async (file) => {
            if (!file) return;

            imagePreviewUrl.value = URL.createObjectURL(file);
            scanState.value   = 'scanning';
            scanError.value   = '';
            decodedRaw.value  = '';
            decodedInfo.value = null;
            isUploading.value = false;

            try {
              // 1. Decode QR locally — no external API
              const { Html5Qrcode } = await import('html5-qrcode');
              const reader = new Html5Qrcode('qrph-hidden-reader');
              const result  = await reader.scanFile(file, false);
              await reader.clear();

              decodedRaw.value = result;
              qrphInput.value  = result;

              // 2. Parse EMV fields
              const parseRes = await axios.post('/Financial/Qrph/Decode', { qrph_code: result });
              if (parseRes.data.success) {
                decodedInfo.value = parseRes.data.decoded;
                // Warn if this is a dynamic (single-use / expiring) QR
                if (parseRes.data.decoded?.initiation_method === 'Dynamic') {
                  if (window.toastr) window.toastr.warning(
                    'This looks like a dynamic (single-use) QR — it may expire. Use your personal static "Receive Money" QR instead.'
                  );
                }
              }

              // 3. Upload the original image so it can be served directly later
              isUploading.value = true;
              const formData = new FormData();
              formData.append('file', file);
              const uploadRes = await axios.post('/File/Upload/QrphPayment', formData, {
                headers: { 'Content-Type': 'multipart/form-data' },
              });
              if (uploadRes.data?.success && uploadRes.data?.hashkey) {
                qrphImgHashkey.value  = uploadRes.data.hashkey;
                // Replace blob URL with the permanent server URL
                imagePreviewUrl.value = `/RequestData/File/${uploadRes.data.hashkey}`;
              }

              scanState.value = 'done';
            } catch (err) {
              if (scanState.value === 'scanning') {
                // QR decode failure
                scanState.value = 'error';
                scanError.value = err?.message?.includes('No MultiFormat Readers')
                  ? 'No QR code found in this image. Try a clearer, higher-resolution screenshot.'
                  : (err?.message || 'Could not read QR code.');
                imagePreviewUrl.value = null;
                decodedRaw.value  = '';
                qrphInput.value   = '';
              } else {
                // Image upload failure — QR was decoded fine, just warn
                if (window.toastr) window.toastr.warning('QR read OK but image upload failed — QRPH string will still be saved.');
                scanState.value = 'done';
              }
            } finally {
              isUploading.value = false;
            }
          };

          const onFileInput = (e) => {
            const file = e.target.files?.[0];
            if (file) scanAndUpload(file);
          };

          const onDrop = (e) => {
            e.preventDefault();
            const file = e.dataTransfer?.files?.[0];
            if (file) scanAndUpload(file);
          };

          const reset = () => {
            scanState.value       = 'idle';
            scanError.value       = '';
            decodedRaw.value      = '';
            decodedInfo.value     = null;
            imagePreviewUrl.value = null;
            qrphInput.value       = '';
            qrphImgHashkey.value  = '';
          };

          const onManualInput = async (e) => {
            decodedRaw.value  = e.target.value;
            qrphInput.value   = e.target.value;
            decodedInfo.value = null;
            if (e.target.value.trim().length > 10) {
              try {
                const res = await axios.post('/Financial/Qrph/Decode', { qrph_code: e.target.value.trim() });
                if (res.data.success) decodedInfo.value = res.data.decoded;
              } catch (_) {}
            }
          };

          return () => h('div', { class: 'qrph-modal-body' }, [

            // Required hidden element for Html5Qrcode
            h('div', { id: 'qrph-hidden-reader', style: 'display:none;' }),

            // ── Drop Zone (not shown once done) ────────────────────────────
            scanState.value !== 'done'
              ? h('label', {
                  class: 'qrph-drop-zone d-flex flex-column align-items-center justify-content-center gap-2 rounded-20 mb-3',
                  style: 'border:2px dashed var(--accent-color,#533dea);min-height:150px;cursor:pointer;background:rgba(83,61,234,0.04);',
                  onDragover: e => e.preventDefault(),
                  onDrop,
                }, [
                  scanState.value === 'scanning'
                    ? h('i', { class: 'fas fa-spinner fa-spin fa-2x', style: 'color:var(--accent-color,#533dea);' })
                    : h('i', { class: 'fas fa-qrcode fa-2x', style: 'color:var(--accent-color,#533dea);opacity:0.7;' }),
                  h('span', { class: 'fw_7', style: 'font-size:13px;color:var(--text-primary);' },
                    scanState.value === 'scanning' ? 'Reading & uploading…' : 'Tap or drop your QR screenshot here'),
                  scanState.value !== 'scanning'
                    ? h('span', { class: 'text-muted', style: 'font-size:11px;' }, 'PNG · JPG · screenshot from GCash / Maya / bank')
                    : null,
                  h('input', { type: 'file', accept: 'image/*', style: 'display:none;', onChange: onFileInput }),
                ])
              : null,

            // ── Error ───────────────────────────────────────────────────────
            scanState.value === 'error'
              ? h('div', { class: 'alert alert-warning d-flex align-items-start gap-2 rounded-20 mb-3', style: 'font-size:12px;' }, [
                  h('i', { class: 'fas fa-exclamation-triangle mt-1 flex-shrink-0' }),
                  h('div', [
                    h('strong', 'Could not read QR: '), scanError.value, h('br'),
                    h('button', { class: 'btn btn-link p-0 smallest text-warning', onClick: reset }, 'Try again'),
                  ]),
                ])
              : null,

            // ── Success card ────────────────────────────────────────────────
            scanState.value === 'done'
              ? h('div', { class: 'd-flex align-items-start gap-3 p-3 rounded-20 mb-3', style: 'background:var(--bg-secondary,#f5f5f5)' }, [
                  imagePreviewUrl.value
                    ? h('img', {
                        src: imagePreviewUrl.value,
                        alt: 'QR',
                        class: 'rounded-15 flex-shrink-0',
                        style: 'width:90px;height:90px;object-fit:contain;background:#fff;padding:4px;',
                      })
                    : null,
                  h('div', { class: 'flex-grow-1' }, [
                    h('p', { class: 'fw_7 mb-1', style: 'font-size:13px;' }, decodedInfo.value?.merchant_name || 'Merchant'),
                    h('p', { class: 'text-muted mb-1', style: 'font-size:11px;' },
                      (decodedInfo.value?.merchant_account?.network || '') +
                      (decodedInfo.value?.merchant_account?.account ? ' · ' + decodedInfo.value.merchant_account.account : '')),
                    h('div', { class: 'd-flex align-items-center gap-2 mb-1 flex-wrap' }, [
                      decodedInfo.value?.valid
                        ? h('span', { class: 'badge bg-success smallest' }, [h('i', { class: 'fas fa-check-circle me-1' }), 'Valid QRPH'])
                        : h('span', { class: 'badge bg-warning text-dark smallest' }, [h('i', { class: 'fas fa-exclamation-triangle me-1' }), 'CRC mismatch']),
                      decodedInfo.value?.initiation_method === 'Static'
                        ? h('span', { class: 'badge bg-primary smallest' }, [h('i', { class: 'fas fa-infinity me-1' }), 'Static (permanent)'])
                        : decodedInfo.value?.initiation_method === 'Dynamic'
                          ? h('span', { class: 'badge bg-danger smallest' }, [h('i', { class: 'fas fa-clock me-1' }), 'Dynamic — may expire!'])
                          : null,
                    ]),
                    isUploading.value
                      ? h('p', { class: 'text-muted smallest mb-0' }, [h('i', { class: 'fas fa-spinner fa-spin me-1' }), 'Uploading image…'])
                      : h('p', { class: 'text-success smallest mb-0' }, [h('i', { class: 'fas fa-image me-1' }), 'Image stored — members will see your actual QR']),
                  ]),
                  h('button', {
                    class: 'btn btn-sm btn-outline-secondary rounded-circle flex-shrink-0',
                    style: 'width:28px;height:28px;padding:0;font-size:10px;',
                    title: 'Use a different QR image',
                    onClick: reset,
                  }, [h('i', { class: 'fas fa-redo' })]),
                ])
              : null,

            // ── Manual fallback ─────────────────────────────────────────────
            h('div', { class: 'mt-2' }, [
              h('button', {
                class: 'btn btn-link p-0 smallest text-muted text-decoration-none',
                onClick: () => { showManual.value = !showManual.value; },
              }, [
                h('i', { class: `fas fa-chevron-${showManual.value ? 'up' : 'down'} me-1` }),
                showManual.value ? 'Hide manual entry' : 'Enter QRPH string manually',
              ]),
              showManual.value
                ? h('div', { class: 'mt-2' }, [
                    h('textarea', {
                      class: 'form-control rounded-20 smallest mt-1',
                      rows: 3,
                      placeholder: '00020101021226…',
                      style: 'font-family:monospace;resize:none;font-size:11px;',
                      value: decodedRaw.value,
                      onInput: onManualInput,
                    }),
                    decodedInfo.value
                      ? h('p', { class: 'text-success smallest mt-1 mb-0' }, [
                          h('i', { class: 'fas fa-check-circle me-1' }),
                          `${decodedInfo.value.merchant_name || 'OK'} · ${decodedInfo.value.merchant_account?.network || ''}`,
                        ])
                      : null,
                  ])
                : null,
            ]),
          ]);
        }
      };

      modal.yesNoModal({
        title: 'Set Payment QR (QRPH)',
        body: h(QrphForm),
        yesText: 'Save',
        noText: 'Cancel',
        onYes: () => saveQrph(),
      });
    };
    // ── End QRPH ────────────────────────────────────────────────────────────

    onMounted(() => {
      if (!userStore.user && !userStore.loading) {
          userStore.fetchCurrentUser();
      }
      fetchQrphCode();
    });

    return {
      user,
      userStore,
      openChangePasswordModal,
      clearCacheAndReload,
      showNotes,
      logout,
      appVersion: __APP_VERSION__,
      buildId: __BUILD_ID__,
      isChangingPassword,
      isPublic,
      accountTypeName,
      openTransferBalanceModal,
      notes,
      loading,
      error,
      fileInput,
      triggerFilePicker,
      onFileSelected,
      isUpdatingPhoto,
      displayPhotoUrl,
      viewFullScreen,
      uiStore,
      toggleDarkMode,
      showTableDensityModal,
      navigate,
      // QRPH
      qrphDecoded,
      openQrphModal,
    };
  }
});
</script>

<style>
.rounded-20 { border-radius: 20px; }
.bg-white-20 { background-color: rgba(255, 255, 255, 0.2); }
.smallest { font-size: 0.75rem; }
.balance-summary-card {
    transition: all 0.2s ease;
}
.balance-summary-card:hover {
    transform: translateY(-2px);
    box-shadow: 0 4px 15px rgba(var(--primary-rgb), 0.3) !important;
}

/* Modal Specific Styles - Non-scoped because modal is teleported */
.change-password-modal-body .input-group-text {
  background-color: var(--bg-card, #fff);
  border-right: none;
  border-radius: 10px 0 0 10px;
  display: flex;
  align-items: center;
  justify-content: center;
  min-width: 50px;
  height: 50px;
}

.change-password-modal-body .form-control {
  border-radius: 0 10px 10px 0;
  border-left: none;
  height: 50px;
  background-color: var(--bg-card, #fff);
  color: var(--text-primary, #1e1e1e);
}

.change-password-modal-body .form-control:focus {
  box-shadow: none;
  border-color: var(--accent-color, #533dea);
}

.change-password-modal-body .input-group-prepend {
  height: 50px;
}

.change-password-modal-body .alert-error {
  background-color: rgba(229, 62, 62, 0.1);
  color: #e53e3e;
  border: 1px solid rgba(229, 62, 62, 0.3);
  border-radius: 10px;
  padding: 10px 15px;
}

/* Modal UI Improvements - Making it flush and premium */
.modal-content {
  border-radius: 24px !important;
  border: none !important;
  box-shadow: 0 20px 40px rgba(0,0,0,0.15) !important;
  overflow: hidden;
  background-color: var(--bg-card, #fff);
}

.modal-header {
  padding: 24px 24px 16px !important;
  border-bottom: none !important;
}

.modal-title {
  font-weight: 800 !important;
  color: var(--text-primary, #1e1e1e);
}

.modal-body {
  padding: 24px !important;
  color: var(--text-primary, #1e1e1e);
}

.modal-footer {
  padding: 8px 24px 24px !important;
  border-top: none !important;
  display: flex !important;
  gap: 12px !important;
}

.modal-footer .btn {
  flex: 1;
  margin: 0 !important;
  height: 52px;
  border-radius: 16px !important;
  font-weight: 700 !important;
  font-size: 16px !important;
  text-transform: none !important;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: all 0.2s ease;
}

.modal-footer .btn-secondary {
  background-color: var(--bg-secondary, #f5f5f5) !important;
  border: none !important;
  color: var(--text-secondary, #717171) !important;
}

.modal-footer .btn-danger, .modal-footer .btn-primary {
  background-color: var(--accent-color, #533dea) !important;
  border: none !important;
  color: #fff !important;
  box-shadow: 0 8px 16px rgba(83, 61, 234, 0.2) !important;
}

.camera-edit-badge {
    position: absolute; 
    bottom: 5px; 
    right: 5px; 
    background: var(--accent-color); 
    color: white; 
    width: 36px; 
    height: 36px; 
    border-radius: 50%; 
    display: flex; 
    align-items: center; 
    justify-content: center; 
    border: 3px solid var(--bg-card); 
    box-shadow: 0 4px 8px rgba(0,0,0,0.15); 
    transition: all 0.2s ease;
}

.list-user-info-container {
    background: var(--bg-card-secondary, rgba(255,255,255,0.05));
    border-radius: 16px;
    overflow: hidden;
    border: 1px solid var(--border-color);
}

.list-user-info {
    border-bottom: 1px solid var(--border-color) !important;
    transition: background 0.2s ease;
}

.list-user-info:hover {
    background: rgba(var(--accent-color-rgb), 0.05);
}

.list-user-info.border-none {
    border-bottom: none !important;
}
</style>
