import { asc, eq } from 'drizzle-orm';
import { crmCustomers, memberships, users } from '@/db/schema';
import { db } from '@/lib/db';
import { getUserBranches } from '@/features/foundation/branch-scope/service';
import { getActiveOptionsByCategory } from '@/features/foundation/master-options/service';
import { hasBranchScopeAccess, hasProductScopeAccess } from '@/lib/auth/crm-access';
import type { CrmReportFilterMetadata, CrmSharedReportFilters } from '../../api/types';
import type { ResolvedReportContext } from '../types';

const PIPELINE_STAGE_OPTIONS = [
  { id: 'lead', code: 'lead', label: 'Lead' },
  { id: 'opportunity', code: 'opportunity', label: 'Opportunity' },
  { id: 'closed_won', code: 'closed_won', label: 'Won' },
  { id: 'closed_lost', code: 'closed_lost', label: 'Lost' }
] as const;

const OUTCOME_OPTIONS = [
  { id: 'open', code: 'open', label: 'Open' },
  { id: 'won', code: 'won', label: 'Won' },
  { id: 'lost', code: 'lost', label: 'Lost' }
] as const;

export async function buildSharedReportFilters(
  context: ResolvedReportContext
): Promise<CrmReportFilterMetadata> {
  const [branches, productTypes, leadSources, lostReasons, customers, memberRows] = await Promise.all([
    getUserBranches(),
    getActiveOptionsByCategory('crm_product_type', { organizationId: context.organizationId }),
    getActiveOptionsByCategory('crm_lead_channel', { organizationId: context.organizationId }),
    getActiveOptionsByCategory('crm_lost_reason', { organizationId: context.organizationId }),
    db
      .select({ id: crmCustomers.id, code: crmCustomers.code, name: crmCustomers.name, branchId: crmCustomers.branchId })
      .from(crmCustomers)
      .where(eq(crmCustomers.organizationId, context.organizationId))
      .orderBy(asc(crmCustomers.name)),
    db
      .select({
        userId: memberships.userId,
        name: users.name
      })
      .from(memberships)
      .innerJoin(users, eq(users.id, memberships.userId))
      .where(eq(memberships.organizationId, context.organizationId))
      .orderBy(asc(users.name))
  ]);

  const visibleBranches = branches.filter((item) => hasBranchScopeAccess(context, item.id));
  const visibleProductTypes = productTypes.filter((item) => hasProductScopeAccess(context, item.id));
  const visibleCustomers = customers.filter((item) => hasBranchScopeAccess(context, item.branchId));
  const uniqueUsers = [...new Map(memberRows.map((row) => [row.userId, row])).values()];

  return {
    branches: visibleBranches.map((item) => ({ id: item.id, code: item.code, label: item.name })),
    productTypes: visibleProductTypes.map((item) => ({
      id: item.id,
      code: item.code,
      label: item.label
    })),
    sales: uniqueUsers.map((item) => ({ id: item.userId, name: item.name })),
    customers: visibleCustomers.map((item) => ({
      id: item.id,
      code: item.code,
      label: item.name
    })),
    customerOwners: uniqueUsers.map((item) => ({ id: item.userId, name: item.name })),
    leadSources: leadSources.map((item) => ({ id: item.id, code: item.code, label: item.label })),
    pipelineStages: PIPELINE_STAGE_OPTIONS.map((item) => ({ ...item })),
    outcomes: OUTCOME_OPTIONS.map((item) => ({ ...item })),
    lostReasons: lostReasons.map((item) => ({ id: item.id, code: item.code, label: item.label }))
  };
}

export function parseSharedReportFilters(searchParams: URLSearchParams): CrmSharedReportFilters {
  return {
    dateFrom: searchParams.get('dateFrom'),
    dateTo: searchParams.get('dateTo'),
    branch: searchParams.get('branch'),
    productType: searchParams.get('productType'),
    sales: searchParams.get('sales'),
    customer: searchParams.get('customer'),
    customerOwner: searchParams.get('customerOwner'),
    leadSource: searchParams.get('leadSource'),
    pipelineStage: searchParams.get('pipelineStage'),
    outcome: searchParams.get('outcome'),
    lostReason: searchParams.get('lostReason')
  };
}

