<script setup lang="ts">
import { computed, onMounted, ref } from 'vue'
import { RouterLink, useRouter } from 'vue-router'
import { getApiErrorMessage } from '@/services/api'
import { customerPortalService, type CustomerPortalAccount, type CustomerPortalDashboard } from '@/modules/customerPortal/services/customerPortalService'
import type { Invoice, PaginationMeta } from '@/modules/invoice/services/invoiceService'

const router = useRouter()
const loading = ref(false)
const error = ref('')
const dashboard = ref<CustomerPortalDashboard | null>(null)
const invoices = ref<Invoice[]>([])
const account = ref<CustomerPortalAccount | null>(readStoredAccount())
const invoiceFilters = ref({
  search: '',
  status: '',
  date_from: '',
  date_to: '',
})
const dueOnly = ref(false)
const invoicePagination = ref<PaginationMeta>({
  current_page: 1,
  from: null,
  last_page: 1,
  per_page: 10,
  to: null,
  total: 0,
})
const profileSaving = ref(false)
const profileError = ref('')
const profileMessage = ref('')
const profileForm = ref({
  name: '',
  email: '',
  current_password: '',
  password: '',
  password_confirmation: '',
})

const companyName = computed(() => account.value?.company.name || 'Customer Portal')
const customerName = computed(() => account.value?.customer.name || account.value?.name || 'Customer')
const hasPasswordChange = computed(() => Boolean(
  profileForm.value.current_password
  || profileForm.value.password
  || profileForm.value.password_confirmation,
))
const latestInvoices = computed(() => dashboard.value?.latest_invoices || [])

function readStoredAccount(): CustomerPortalAccount | null {
  const stored = localStorage.getItem('customer_portal_account')

  return stored ? JSON.parse(stored) as CustomerPortalAccount : null
}

async function load() {
  loading.value = true
  error.value = ''

  try {
    const [accountData, dashboardData, invoiceData] = await Promise.all([
      customerPortalService.me(),
      customerPortalService.dashboard(),
      customerPortalService.paginatedInvoices({
        search: invoiceFilters.value.search || undefined,
        status: invoiceFilters.value.status || undefined,
        date_from: invoiceFilters.value.date_from || undefined,
        date_to: invoiceFilters.value.date_to || undefined,
        due_only: dueOnly.value || undefined,
        page: invoicePagination.value.current_page,
        per_page: invoicePagination.value.per_page,
      }),
    ])
    account.value = accountData
    dashboard.value = dashboardData
    invoices.value = invoiceData.data
    invoicePagination.value = invoiceData.meta
    resetProfileForm(accountData)
    localStorage.setItem('customer_portal_account', JSON.stringify(accountData))
  } catch (loadError) {
    error.value = getApiErrorMessage(loadError, 'Unable to load customer portal data.')
  } finally {
    loading.value = false
  }
}

async function applyInvoiceFilters() {
  invoicePagination.value.current_page = 1
  await load()
}

async function resetInvoiceFilters() {
  invoiceFilters.value = {
    search: '',
    status: '',
    date_from: '',
    date_to: '',
  }
  dueOnly.value = false
  invoicePagination.value.current_page = 1
  await load()
}

async function loadInvoicePage(page: number) {
  invoicePagination.value.current_page = Math.min(Math.max(page, 1), invoicePagination.value.last_page || 1)
  await load()
}

function resetProfileForm(accountData = account.value) {
  profileForm.value = {
    name: accountData?.name || '',
    email: accountData?.email || '',
    current_password: '',
    password: '',
    password_confirmation: '',
  }
}

async function updateProfile() {
  profileSaving.value = true
  profileError.value = ''
  profileMessage.value = ''

  if (hasPasswordChange.value && !profileForm.value.current_password) {
    profileError.value = 'Current password is required to change password.'
    profileSaving.value = false
    return
  }

  if (profileForm.value.password && profileForm.value.password !== profileForm.value.password_confirmation) {
    profileError.value = 'Password confirmation does not match.'
    profileSaving.value = false
    return
  }

  try {
    const updatedAccount = await customerPortalService.updateProfile({
      name: profileForm.value.name.trim(),
      email: profileForm.value.email.trim(),
      current_password: profileForm.value.current_password || undefined,
      password: profileForm.value.password || undefined,
      password_confirmation: profileForm.value.password_confirmation || undefined,
    })
    account.value = updatedAccount
    localStorage.setItem('customer_portal_account', JSON.stringify(updatedAccount))
    resetProfileForm(updatedAccount)
    profileMessage.value = 'Account settings saved.'
  } catch (profileUpdateError) {
    profileError.value = getApiErrorMessage(profileUpdateError, 'Unable to save account settings.')
  } finally {
    profileSaving.value = false
  }
}

async function logout() {
  await customerPortalService.logout().catch(() => undefined)
  localStorage.removeItem('customer_portal_token')
  localStorage.removeItem('customer_portal_account')
  await router.push('/customer-portal/login')
}

function money(value: string | number | undefined) {
  return Number(value || 0).toFixed(2)
}

function statusLabel(status: string) {
  return status.charAt(0).toUpperCase() + status.slice(1).replace('_', ' ')
}

function statusClass(status: string) {
  return {
    off: ['cancelled', 'draft'].includes(status),
    warn: ['sent', 'partial'].includes(status),
  }
}

onMounted(load)
</script>

<template>
  <main class="portal-layout">
    <section class="portal-workspace">
      <header class="portal-header">
        <div>
          <p class="eyebrow">Customer Portal</p>
          <h1>{{ companyName }}</h1>
          <p>{{ customerName }} - {{ account?.email }}</p>
        </div>
        <button class="button ghost" type="button" @click="logout">Logout</button>
      </header>

      <p v-if="error" class="error">{{ error }}</p>
      <p v-if="loading">Loading portal data...</p>

      <section v-if="dashboard" class="grid">
        <article class="metric">
          <span>Total Invoices</span>
          <strong>{{ dashboard.total_invoices }}</strong>
        </article>
        <article class="metric">
          <span>Unpaid</span>
          <strong>{{ dashboard.unpaid_invoices }}</strong>
        </article>
        <article class="metric">
          <span>Overdue</span>
          <strong>{{ dashboard.overdue_invoices }}</strong>
        </article>
        <article class="metric">
          <span>Total Due</span>
          <strong>BDT {{ dashboard.total_due }}</strong>
        </article>
      </section>

      <section v-if="dashboard && Number(dashboard.total_due) > 0" class="notice-bar portal-notice">
        <div>
          <strong>Outstanding balance</strong>
          <span>{{ dashboard.unpaid_invoices }} unpaid invoice(s), {{ dashboard.overdue_invoices }} overdue.</span>
        </div>
        <button class="button ghost" type="button" @click="dueOnly = true; applyInvoiceFilters()">View Due</button>
      </section>

      <article class="panel">
        <div class="portal-section-header">
          <h2>Account Settings</h2>
          <span class="status-pill" :class="{ off: account?.status !== 'active' }">{{ account?.status || 'active' }}</span>
        </div>
        <form class="form" @submit.prevent="updateProfile">
          <p v-if="profileError" class="error">{{ profileError }}</p>
          <p v-if="profileMessage" class="success">{{ profileMessage }}</p>
          <div class="grid compact-grid">
            <div class="field">
              <label for="portal_profile_name">Name</label>
              <input id="portal_profile_name" v-model="profileForm.name" type="text" required />
            </div>
            <div class="field">
              <label for="portal_profile_email">Email</label>
              <input id="portal_profile_email" v-model="profileForm.email" type="email" required />
            </div>
          </div>
          <p class="muted">Password fields are optional. Fill all password fields only when changing the password.</p>
          <div class="grid compact-grid">
            <div class="field">
              <label for="portal_current_password">Current Password</label>
              <input id="portal_current_password" v-model="profileForm.current_password" autocomplete="current-password" type="password" />
            </div>
            <div class="field">
              <label for="portal_new_password">New Password</label>
              <input id="portal_new_password" v-model="profileForm.password" autocomplete="new-password" type="password" />
            </div>
            <div class="field">
              <label for="portal_confirm_password">Confirm Password</label>
              <input id="portal_confirm_password" v-model="profileForm.password_confirmation" autocomplete="new-password" type="password" />
            </div>
          </div>
          <div class="inline-actions">
            <button class="button primary" type="submit" :disabled="profileSaving">Save Settings</button>
            <button class="button ghost" type="button" :disabled="profileSaving" @click="resetProfileForm()">Reset</button>
          </div>
        </form>
      </article>

      <article v-if="latestInvoices.length" class="panel">
        <div class="portal-section-header">
          <h2>Latest Invoices</h2>
          <span class="muted">{{ latestInvoices.length }} recent</span>
        </div>
        <div class="portal-table">
          <RouterLink v-for="invoice in latestInvoices" :key="invoice.id" class="portal-row" :to="`/customer-portal/invoices/${invoice.id}`">
            <span>
              <strong>{{ invoice.invoice_number }}</strong>
              <small>{{ invoice.issue_date }} - Due {{ invoice.due_date || 'N/A' }}</small>
            </span>
            <span class="status-pill" :class="statusClass(invoice.status)">{{ statusLabel(invoice.status) }}</span>
            <span>BDT {{ money(invoice.due_total) }} due</span>
          </RouterLink>
        </div>
      </article>

      <article class="panel">
        <div class="portal-section-header">
          <h2>Invoices</h2>
          <form class="inline-actions" @submit.prevent="applyInvoiceFilters">
            <input v-model="invoiceFilters.search" aria-label="Search invoices" type="search" placeholder="Search invoice" />
            <select v-model="invoiceFilters.status" aria-label="Status">
              <option value="">All</option>
              <option value="draft">Draft</option>
              <option value="sent">Sent</option>
              <option value="partial">Partial</option>
              <option value="paid">Paid</option>
              <option value="cancelled">Cancelled</option>
            </select>
            <input v-model="invoiceFilters.date_from" aria-label="Date from" type="date" />
            <input v-model="invoiceFilters.date_to" aria-label="Date to" type="date" />
            <label class="inline-check">
              <input v-model="dueOnly" type="checkbox" />
              Due only
            </label>
            <button class="button primary" type="submit" :disabled="loading">Apply</button>
            <button class="button ghost" type="button" :disabled="loading" @click="resetInvoiceFilters">Reset</button>
          </form>
        </div>

        <div class="portal-table">
          <RouterLink v-for="invoice in invoices" :key="invoice.id" class="portal-row" :to="`/customer-portal/invoices/${invoice.id}`">
            <span>
              <strong>{{ invoice.invoice_number }}</strong>
              <small>{{ invoice.issue_date }} - Due {{ invoice.due_date || 'N/A' }}</small>
            </span>
            <span class="status-pill" :class="statusClass(invoice.status)">{{ statusLabel(invoice.status) }}</span>
            <span>BDT {{ money(invoice.due_total) }} due</span>
          </RouterLink>
        </div>
        <p v-if="invoices.length === 0 && !loading">No invoices found.</p>
        <div class="inline-actions portal-pagination">
          <span>
            Showing {{ invoicePagination.from || 0 }}-{{ invoicePagination.to || 0 }} of {{ invoicePagination.total }}
          </span>
          <button
            class="button ghost"
            type="button"
            :disabled="loading || invoicePagination.current_page <= 1"
            @click="loadInvoicePage(invoicePagination.current_page - 1)"
          >
            Previous
          </button>
          <span>Page {{ invoicePagination.current_page }} of {{ invoicePagination.last_page }}</span>
          <button
            class="button ghost"
            type="button"
            :disabled="loading || invoicePagination.current_page >= invoicePagination.last_page"
            @click="loadInvoicePage(invoicePagination.current_page + 1)"
          >
            Next
          </button>
        </div>
      </article>
    </section>
  </main>
</template>
