// ---------------------------------------------------------------------------
// DemoProvider — DataProvider implementation backed by in-memory Zustand store
// ---------------------------------------------------------------------------

import type { DataProvider } from './data-provider';
import type { DocumentListParams } from '@/lib/api/documents';
import { useDemoStore } from './demo-store';
import { buildKanbanResponse } from './mock-data/tasks';
import { demoStaticData } from './mock-data/lookups';
import { demoUser } from './mock-data/user';

// ---------------------------------------------------------------------------
// Helper: read current store state (snapshot) outside React
// ---------------------------------------------------------------------------
function snap() {
  return useDemoStore.getState();
}

// ---------------------------------------------------------------------------
// Provider
// ---------------------------------------------------------------------------

export const demoProvider: DataProvider = {
  basePath: '/demo/app',

  // -----------------------------------------------------------------------
  // Residences
  // -----------------------------------------------------------------------
  residences: {
    list: async () => snap().residences,
    get: async (id) => {
      const r = snap().residences.find(r => r.id === id);
      if (!r) throw new Error(`Residence ${id} not found`);
      return r;
    },
    create: async (data) => {
      const staticData = demoStaticData;
      const propertyType = data.property_type_id
        ? staticData.residence_types.find(t => t.id === data.property_type_id)
        : undefined;
      return snap().addResidence({ ...data, property_type: propertyType });
    },
    update: async (id, data) => snap().updateResidence(id, data),
    delete: async (id) => {
      snap().deleteResidence(id);
      return { message: 'Residence deleted' };
    },
    getMyResidences: async () => snap().myResidences,
    getSummary: async () => {
      const { residences, myResidences } = snap();
      const totalSummary = myResidences.reduce(
        (acc, mr) => ({
          total: acc.total + mr.task_summary.total,
          overdue: acc.overdue + mr.task_summary.overdue,
          due_soon: acc.due_soon + mr.task_summary.due_soon,
          in_progress: acc.in_progress + mr.task_summary.in_progress,
          completed: acc.completed + mr.task_summary.completed,
        }),
        { total: 0, overdue: 0, due_soon: 0, in_progress: 0, completed: 0 },
      );
      return {
        total_residences: residences.length,
        total_summary: totalSummary,
        residences: myResidences,
      };
    },
  },

  // -----------------------------------------------------------------------
  // Tasks
  // -----------------------------------------------------------------------
  tasks: {
    list: async () => buildKanbanResponse(snap().tasks),
    get: async (id) => {
      const t = snap().tasks.find(t => t.id === id);
      if (!t) throw new Error(`Task ${id} not found`);
      return t;
    },
    create: async (data) => {
      const staticData = demoStaticData;
      const category = data.category_id
        ? staticData.task_categories.find(c => c.id === data.category_id)
        : undefined;
      const priority = data.priority_id
        ? staticData.task_priorities.find(p => p.id === data.priority_id)
        : undefined;
      const contractor = data.contractor_id
        ? snap().contractors.find(c => c.id === data.contractor_id)
        : undefined;
      return snap().addTask({
        ...data,
        category: category ? { ...category } : undefined,
        priority: priority ? { ...priority } : undefined,
        contractor: contractor
          ? { id: contractor.id, name: contractor.name, company: contractor.company }
          : undefined,
      });
    },
    update: async (id, data) => {
      const staticData = demoStaticData;
      const extra: Record<string, unknown> = {};
      if (data.category_id != null) {
        extra.category = staticData.task_categories.find(c => c.id === data.category_id);
      }
      if (data.priority_id != null) {
        extra.priority = staticData.task_priorities.find(p => p.id === data.priority_id);
      }
      if (data.contractor_id != null) {
        const c = snap().contractors.find(c => c.id === data.contractor_id);
        extra.contractor = c ? { id: c.id, name: c.name, company: c.company } : undefined;
      }
      return snap().updateTask(id, { ...data, ...extra });
    },
    delete: async (id) => {
      snap().deleteTask(id);
      return { message: 'Task deleted' };
    },
    getByResidence: async (residenceId) => {
      const tasks = snap().tasks.filter(t => t.residence_id === residenceId);
      return buildKanbanResponse(tasks);
    },
    getCompletions: async (taskId) =>
      snap().completions.filter(c => c.task_id === taskId),
    createCompletion: async (data) =>
      snap().completeTask(data.task_id, data),
    createCompletionWithImages: async (data) =>
      snap().completeTask(data.task_id, data),
    markInProgress: async (id) => snap().markTaskInProgress(id),
    cancel: async (id) => snap().cancelTask(id),
    uncancel: async (id) => snap().uncancelTask(id),
    archive: async (id) => snap().archiveTask(id),
    unarchive: async (id) => snap().unarchiveTask(id),
    quickComplete: async (id) => {
      snap().completeTask(id, {});
    },
  },

  // -----------------------------------------------------------------------
  // Contractors
  // -----------------------------------------------------------------------
  contractors: {
    list: async () => snap().contractors,
    get: async (id) => {
      const c = snap().contractors.find(c => c.id === id);
      if (!c) throw new Error(`Contractor ${id} not found`);
      return c;
    },
    create: async (data) => {
      const specialties = (data.specialty_ids ?? [])
        .map(sid => demoStaticData.contractor_specialties.find(s => s.id === sid))
        .filter(Boolean) as { id: number; name: string; icon: string }[];
      return snap().addContractor({ ...data, specialties });
    },
    update: async (id, data) => {
      const extra: Record<string, unknown> = {};
      if (data.specialty_ids) {
        extra.specialties = data.specialty_ids
          .map(sid => demoStaticData.contractor_specialties.find(s => s.id === sid))
          .filter(Boolean);
      }
      return snap().updateContractor(id, { ...data, ...extra });
    },
    delete: async (id) => {
      snap().deleteContractor(id);
      return { message: 'Contractor deleted' };
    },
    toggleFavorite: async (id) => {
      const updated = snap().toggleContractorFavorite(id);
      return { id: updated.id, is_favorite: updated.is_favorite };
    },
    getTasks: async (id) => {
      const tasks = snap().tasks.filter(t => t.contractor_id === id);
      return tasks.map(t => ({
        id: t.id,
        title: t.title,
        residence_name: t.residence_name,
        status: t.in_progress ? 'in_progress' : t.is_cancelled ? 'cancelled' : 'pending',
        due_date: t.due_date,
        priority: t.priority?.name,
      }));
    },
  },

  // -----------------------------------------------------------------------
  // Documents
  // -----------------------------------------------------------------------
  documents: {
    list: async (params?: DocumentListParams) => {
      let docs = snap().documents;
      if (params?.residence) docs = docs.filter(d => d.residence_id === params.residence);
      if (params?.document_type) docs = docs.filter(d => d.document_type === params.document_type);
      if (params?.is_active != null) docs = docs.filter(d => d.is_active === params.is_active);
      if (params?.search) {
        const q = params.search.toLowerCase();
        docs = docs.filter(d =>
          d.title.toLowerCase().includes(q) || d.description.toLowerCase().includes(q),
        );
      }
      return docs;
    },
    listWarranties: async () =>
      snap().documents.filter(d => d.document_type === 'warranty'),
    get: async (id) => {
      const d = snap().documents.find(d => d.id === id);
      if (!d) throw new Error(`Document ${id} not found`);
      return d;
    },
    create: async (data) => {
      const residence = snap().residences.find(r => r.id === data.residence_id);
      return snap().addDocument({
        ...data,
        residence_name: residence?.name,
      });
    },
    createWithFile: async (data) => {
      const residence = snap().residences.find(r => r.id === data.residence_id);
      return snap().addDocument({
        ...data,
        residence_name: residence?.name,
      });
    },
    update: async (id, data) => snap().updateDocument(id, data),
    delete: async (id) => {
      snap().deleteDocument(id);
      return { message: 'Document deleted' };
    },
  },

  // -----------------------------------------------------------------------
  // Lookups
  // -----------------------------------------------------------------------
  lookups: {
    getStaticData: async () => demoStaticData,
  },

  // -----------------------------------------------------------------------
  // Sharing (demo stubs — mostly no-ops or simple responses)
  // -----------------------------------------------------------------------
  sharing: {
    getShareCode: async () => ({ share_code: null }),
    generateShareCode: async (residenceId) => ({
      code: 'DEMO42',
      residence_id: residenceId,
      expires_at: new Date(Date.now() + 24 * 3600000).toISOString(),
      created_at: new Date().toISOString(),
    }),
    generateSharePackage: async (residenceId) => {
      const r = snap().residences.find(r => r.id === residenceId);
      return {
        code: 'DEMO42',
        residence_id: residenceId,
        residence_name: r?.name ?? 'Demo Residence',
        owner_name: 'Demo User',
        expires_at: new Date(Date.now() + 24 * 3600000).toISOString(),
      };
    },
    getResidenceUsers: async () => [
      {
        id: 1,
        username: 'demo_user',
        email: 'demo@honeyDue.treytartt.com',
        first_name: 'Demo',
        last_name: 'User',
        is_owner: true,
      },
    ],
    removeUser: async () => ({ message: 'User removed' }),
    joinWithCode: async () => {
      throw new Error('Sharing is not available in demo mode');
    },
    generateTasksReport: async (residenceId) => {
      const r = snap().residences.find(r => r.id === residenceId);
      return {
        message: 'Report generated (demo)',
        residence_name: r?.name ?? 'Demo Residence',
        recipient_email: 'demo@honeyDue.treytartt.com',
        pdf_generated: true,
        email_sent: false,
        report: {},
      };
    },
  },

  // -----------------------------------------------------------------------
  // Notifications
  // -----------------------------------------------------------------------
  notifications: {
    list: async (limit, offset) => {
      let items = snap().notifications;
      const start = offset ?? 0;
      const end = limit ? start + limit : undefined;
      items = items.slice(start, end);
      return { count: snap().notifications.length, results: items };
    },
    getUnreadCount: async () => ({
      unread_count: snap().notifications.filter(n => !n.is_read).length,
    }),
    getPreferences: async () => ({
      task_reminders: true,
      task_completions: true,
      residence_updates: true,
      share_notifications: true,
      marketing: false,
    }),
    updatePreferences: async (data) => ({
      task_reminders: data.task_reminders ?? true,
      task_completions: data.task_completions ?? true,
      residence_updates: data.residence_updates ?? true,
      share_notifications: data.share_notifications ?? true,
      marketing: data.marketing ?? false,
    }),
    markAsRead: async (id) => {
      snap().markNotificationRead(id);
      return { message: 'Marked as read' };
    },
    markAllAsRead: async () => {
      snap().markAllNotificationsRead();
      return { message: 'All marked as read' };
    },
  },

  // -----------------------------------------------------------------------
  // Subscription (mock free tier)
  // -----------------------------------------------------------------------
  subscription: {
    getStatus: async () => ({
      tier: 'free',
      is_active: true,
      auto_renew: false,
      limits: {
        free: { properties: 2, tasks: 25, contractors: 10, documents: 20 },
        pro: { properties: null, tasks: null, contractors: null, documents: null },
      },
      limitations_enabled: true,
    }),
    getFeatureBenefits: async () => [
      { feature_name: 'Unlimited Residences', free_tier_text: 'Up to 2', pro_tier_text: 'Unlimited', display_order: 1 },
      { feature_name: 'Unlimited Tasks', free_tier_text: 'Up to 25', pro_tier_text: 'Unlimited', display_order: 2 },
      { feature_name: 'Sharing', free_tier_text: 'No', pro_tier_text: 'Yes', display_order: 3 },
      { feature_name: 'PDF Reports', free_tier_text: 'No', pro_tier_text: 'Yes', display_order: 4 },
    ],
    getUpgradeTriggers: async () => [
      { trigger_key: 'residence_limit', title: 'Need more properties?', message: 'Upgrade to track unlimited residences.', promo_html: '', button_text: 'Upgrade' },
      { trigger_key: 'sharing', title: 'Want to share?', message: 'Upgrade to share residences with family members.', promo_html: '', button_text: 'Upgrade' },
    ],
  },

  // -----------------------------------------------------------------------
  // Auth (demo user)
  // -----------------------------------------------------------------------
  auth: {
    getCurrentUser: async () => demoUser,
    logout: async () => ({ message: 'Logged out' }),
  },
};
