import React, { useState, useEffect, useMemo } from 'react';
import { supabase } from '@/integrations/supabase/client';
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
import { cn } from '@/lib/utils';
import { fetchChartOfAccounts } from '@/lib/chartOfAccountsSource';

const NONE_VALUE = '__none__';

const normalizeType = (type) => String(type || '').trim().toLowerCase();

const accountTypeMatches = (accountType, filterType) => {
  if (!filterType) return true;
  const normalizedAccountType = normalizeType(accountType).replace(/[\s-]+/g, '_');
  const normalizedFilterType = normalizeType(filterType).replace(/[\s-]+/g, '_');
  if (normalizedAccountType === normalizedFilterType) return true;
  if (normalizedFilterType === 'expense') return normalizedAccountType.includes('expense') || normalizedAccountType === 'cost_of_goods_sold';
  return false;
};

const isAssignedToAssociation = (account, associationId) => {
  if (!associationId) return true;
  const associationIds = Array.isArray(account.association_ids) ? account.association_ids : [];
  return account.association_id === associationId || associationIds.includes(associationId);
};

const isUnassignedGlobalAccount = (account) => {
  const associationIds = Array.isArray(account.association_ids) ? account.association_ids : [];
  return !account.association_id && associationIds.length === 0;
};

export default function ChartOfAccountsDropdown({ value, onChange, className, placeholder = "Account", accountType = null, associationId = null, disabled = false }) {
  const [accounts, setAccounts] = useState([]);

  useEffect(() => {
    const fetch = async () => {
      // Resolve which accounting system this association uses (platform / zoho / buildium)
      let system = 'buildium';
      if (associationId) {
        const { data: assoc } = await supabase
          .from('associations')
          .select('accounting_system, zoho_organization_id')
          .eq('id', associationId)
          .maybeSingle();
        const explicit = assoc?.accounting_system;
        if (explicit === 'platform' || explicit === 'zoho' || explicit === 'buildium') {
          system = explicit;
        } else if (assoc?.zoho_organization_id && String(assoc.zoho_organization_id).trim() !== '') {
          system = 'zoho';
        }
      }

      // Single normalized source: accounting.accounts for platform, else public COA.
      const allAccounts = await fetchChartOfAccounts(associationId, system);

      const filtered = allAccounts.filter((account) => {
        const matchesType = accountTypeMatches(account.account_type, accountType);
        const matchesSystem = normalizeType(account.accounting_system || 'buildium') === system;
        const matchesAssociation = isAssignedToAssociation(account, associationId);

        return matchesType && (matchesAssociation || (matchesSystem && isUnassignedGlobalAccount(account)));
      });

      setAccounts(filtered);
    };
    fetch();
  }, [accountType, associationId]);

  // Sort accounts hierarchically: parents first, then their children (by account_number)
  const orderedAccounts = useMemo(() => {
    const byId = new Map(accounts.map(a => [a.id, a]));
    const childrenByParent = new Map();
    const roots = [];
    accounts.forEach(a => {
      if (a.parent_account_id && byId.has(a.parent_account_id)) {
        if (!childrenByParent.has(a.parent_account_id)) childrenByParent.set(a.parent_account_id, []);
        childrenByParent.get(a.parent_account_id).push(a);
      } else {
        roots.push(a);
      }
    });
    const sortFn = (a, b) => String(a.account_number || '').localeCompare(String(b.account_number || ''));
    roots.sort(sortFn);
    const out = [];
    const visit = (node, depth) => {
      out.push({ ...node, _depth: depth });
      const kids = (childrenByParent.get(node.id) || []).sort(sortFn);
      kids.forEach(k => visit(k, depth + 1));
    };
    roots.forEach(r => visit(r, 0));
    return out;
  }, [accounts]);

  return (
    <Select value={value || undefined} onValueChange={(nextValue) => onChange(nextValue === NONE_VALUE ? '' : nextValue)} disabled={disabled}>
      <SelectTrigger className={cn("text-xs", className)}>
        <SelectValue placeholder={placeholder} />
      </SelectTrigger>
      <SelectContent className="max-h-[400px]">
        <SelectItem value={NONE_VALUE}>None</SelectItem>
        {orderedAccounts.map(a => (
          <SelectItem key={a.id} value={a.id}>
            <span style={{ paddingLeft: `${(a._depth || 0) * 12}px` }}>
              {a._depth > 0 ? '↳ ' : ''}{a.account_number} - {a.account_name}
            </span>
          </SelectItem>
        ))}
      </SelectContent>
    </Select>
  );
}
