import { NextRequest, NextResponse } from 'next/server';
import {
  NIGERIAN_STATES,
  LGAS_BY_STATE,
  WARDS_BY_LGA,
  POLLING_UNITS_BY_WARD,
  INITIAL_PU_RESULTS
} from '@/lib/electoralData';

type FormType = 'EC8A' | 'EC8B' | 'EC8C' | 'EC8D' | 'EC8E';

// Helper: Convert numbers to words for formal Nigerian election statutory forms
function numberToWords(num: number): string {
  if (num === 0) return 'ZERO';
  const ones = ['', 'ONE', 'TWO', 'THREE', 'FOUR', 'FIVE', 'SIX', 'SEVEN', 'EIGHT', 'NINE',
    'TEN', 'ELEVEN', 'TWELVE', 'THIRTEEN', 'FOURTEEN', 'FIFTEEN', 'SIXTEEN', 'SEVENTEEN', 'EIGHTEEN', 'NINETEEN'];
  const tens = ['', '', 'TWENTY', 'THIRTY', 'FORTY', 'FIFTY', 'SIXTY', 'SEVENTY', 'EIGHTY', 'NINETY'];

  if (num < 20) return ones[num];
  if (num < 100) return tens[Math.floor(num / 10)] + (num % 10 !== 0 ? ' ' + ones[num % 10] : '');
  if (num < 1000) {
    return ones[Math.floor(num / 100)] + ' HUNDRED' + (num % 100 !== 0 ? ' AND ' + numberToWords(num % 100) : '');
  }
  if (num < 1000000) {
    return numberToWords(Math.floor(num / 1000)) + ' THOUSAND' + (num % 1000 !== 0 ? ' ' + numberToWords(num % 1000) : '');
  }
  if (num < 1000000000) {
    return numberToWords(Math.floor(num / 1000000)) + ' MILLION' + (num % 1000000 !== 0 ? ' ' + numberToWords(num % 1000000) : '');
  }
  return num.toLocaleString();
}

export async function GET(request: NextRequest) {
  try {
    const { searchParams } = new URL(request.url);
    const form = (searchParams.get('form') || searchParams.get('type') || 'EC8E').toUpperCase() as FormType;
    const format = (searchParams.get('format') || 'json').toLowerCase();

    const stateId = searchParams.get('state_id') || '24';
    const lgaId = searchParams.get('lga_id') || '24-11';
    const wardId = searchParams.get('ward_id') || '24-11-01';
    const puCode = searchParams.get('pu_code') || '24-11-01-001';

    // Lookups
    const stateObj = NIGERIAN_STATES.find((s) => s.id === stateId) || NIGERIAN_STATES[0];
    const lgas = LGAS_BY_STATE[stateId] || [];
    const lgaObj = lgas.find((l) => l.id === lgaId) || lgas[0];
    const wards = WARDS_BY_LGA[lgaId] || [];
    const wardObj = wards.find((w) => w.id === wardId) || wards[0];
    const pus = POLLING_UNITS_BY_WARD[wardId] || [];
    const puObj = pus.find((p) => p.pu_code === puCode) || pus[0];

    // Compute Form Data
    let formData: any = null;

    if (form === 'EC8A') {
      const puResult = INITIAL_PU_RESULTS[puCode] || {
        registered_voters: puObj?.registered_voters || 750,
        accredited_voters: 0,
        party_votes: { ADC: 0, APC: 0, PDP: 0, LP: 0, NNPP: 0, SDP: 0 },
        total_valid_votes: 0,
        rejected_ballots: 0,
        total_votes_cast: 0,
      };

      formData = {
        form_type: 'EC8A',
        title: 'FORM EC 8A: POLLING UNIT RESULTS OF ELECTION',
        pu_code: puCode,
        pu_name: puObj?.pu_name || `Polling Unit ${puCode}`,
        ward: wardObj?.name || 'Ward',
        lga: lgaObj?.name || 'LGA',
        state: stateObj?.name || 'State',
        registered_voters: puResult.registered_voters,
        accredited_voters: puResult.accredited_voters,
        valid_votes: puResult.total_valid_votes || 0,
        rejected_ballots: puResult.rejected_ballots || 0,
        total_votes_cast: puResult.total_votes_cast || 0,
        votes: {
          ADC: puResult.party_votes?.ADC || 0,
          APC: puResult.party_votes?.APC || 0,
          PDP: puResult.party_votes?.PDP || 0,
          LP: puResult.party_votes?.LP || 0,
          NNPP: puResult.party_votes?.NNPP || 0,
          SDP: puResult.party_votes?.SDP || 0,
        },
        officer: 'Presiding Officer (PO)',
      };
    } else if (form === 'EC8B') {
      const reg = wardObj?.registered_voters || 0;
      const adc = wardObj?.votes?.ADC || 0;
      const apc = wardObj?.votes?.APC || 0;
      const pdp = wardObj?.votes?.PDP || 0;
      const lp = wardObj?.votes?.LP || 0;
      const nnpp = wardObj?.votes?.NNPP || 0;
      const sdp = wardObj?.votes?.SDP || 0;
      const valid = adc + apc + pdp + lp + nnpp + sdp;
      const acc = valid;
      const rejected = 0;

      formData = {
        form_type: 'EC8B',
        title: 'FORM EC 8B: SUMMARY OF RESULTS AT REGISTRATION AREA (WARD) COLLATION',
        ward_id: wardId,
        ward_name: wardObj?.name || 'Ward',
        lga: lgaObj?.name || 'LGA',
        state: stateObj?.name || 'State',
        registered_voters: reg,
        accredited_voters: acc,
        valid_votes: valid,
        rejected_ballots: rejected,
        total_votes_cast: valid + rejected,
        votes: { ADC: adc, APC: apc, PDP: pdp, LP: lp, NNPP: nnpp, SDP: sdp },
        officer: 'Ward Collation Officer (RACO)',
      };
    } else if (form === 'EC8C') {
      const reg = lgaObj?.registered_voters || 0;
      const adc = lgaObj?.votes?.ADC || 0;
      const apc = lgaObj?.votes?.APC || 0;
      const pdp = lgaObj?.votes?.PDP || 0;
      const lp = lgaObj?.votes?.LP || 0;
      const nnpp = lgaObj?.votes?.NNPP || 0;
      const sdp = lgaObj?.votes?.SDP || 0;
      const valid = adc + apc + pdp + lp + nnpp + sdp;
      const acc = valid;
      const rejected = 0;

      formData = {
        form_type: 'EC8C',
        title: 'FORM EC 8C: SUMMARY OF RESULTS AT LOCAL GOVERNMENT AREA COLLATION',
        lga_id: lgaId,
        lga_name: lgaObj?.name || 'LGA',
        state: stateObj?.name || 'State',
        registered_voters: reg,
        accredited_voters: acc,
        valid_votes: valid,
        rejected_ballots: rejected,
        total_votes_cast: valid + rejected,
        votes: { ADC: adc, APC: apc, PDP: pdp, LP: lp, NNPP: nnpp, SDP: sdp },
        officer: 'LGA Collation Officer (LGACO)',
      };
    } else if (form === 'EC8D') {
      const reg = stateObj?.registered_voters || 0;
      const adc = stateObj?.votes?.ADC || 0;
      const apc = stateObj?.votes?.APC || 0;
      const pdp = stateObj?.votes?.PDP || 0;
      const lp = stateObj?.votes?.LP || 0;
      const nnpp = stateObj?.votes?.NNPP || 0;
      const sdp = stateObj?.votes?.SDP || 0;
      const valid = adc + apc + pdp + lp + nnpp + sdp;
      const acc = valid;
      const rejected = 0;

      formData = {
        form_type: 'EC8D',
        title: 'FORM EC 8D: SUMMARY OF RESULTS AT STATE COLLATION',
        state_id: stateId,
        state_name: stateObj?.name || 'State',
        registered_voters: reg,
        accredited_voters: acc,
        valid_votes: valid,
        rejected_ballots: rejected,
        total_votes_cast: valid + rejected,
        votes: { ADC: adc, APC: apc, PDP: pdp, LP: lp, NNPP: nnpp, SDP: sdp },
        officer: 'State Collation Officer (SCOPE)',
      };
    } else {
      // EC8E National Declaration
      const totalReg = NIGERIAN_STATES.reduce((acc, s) => acc + s.registered_voters, 0);
      const adcVotes = NIGERIAN_STATES.reduce((acc, s) => acc + (s.votes?.ADC || 0), 0);
      const apcVotes = NIGERIAN_STATES.reduce((acc, s) => acc + (s.votes?.APC || 0), 0);
      const pdpVotes = NIGERIAN_STATES.reduce((acc, s) => acc + (s.votes?.PDP || 0), 0);
      const lpVotes = NIGERIAN_STATES.reduce((acc, s) => acc + (s.votes?.LP || 0), 0);
      const nnppVotes = NIGERIAN_STATES.reduce((acc, s) => acc + (s.votes?.NNPP || 0), 0);
      const sdpVotes = NIGERIAN_STATES.reduce((acc, s) => acc + (s.votes?.SDP || 0), 0);
      const valid = adcVotes + apcVotes + pdpVotes + lpVotes + nnppVotes + sdpVotes;
      const totalAcc = valid;
      const rejected = 0;
      const winner = valid > 0 ? (adcVotes > apcVotes ? 'H.E. ATIKU ABUBAKAR (GCON) - ADC' : 'APC') : 'AWAITING NATIONAL COLLATION';

      formData = {
        form_type: 'EC8E',
        title: 'FORM EC 8E: DECLARATION OF RESULT OF ELECTION (NATIONAL SUMMARY)',
        jurisdiction: 'Federal Republic of Nigeria (36 States + FCT Abuja)',
        registered_voters: totalReg,
        accredited_voters: totalAcc,
        valid_votes: valid,
        rejected_ballots: rejected,
        total_votes_cast: valid + rejected,
        votes: { ADC: adcVotes, APC: apcVotes, PDP: pdpVotes, LP: lpVotes, NNPP: nnppVotes, SDP: sdpVotes },
        winner,
        officer: 'Chief Electoral Commissioner & Returning Officer of the Federation',
      };
    }

    if (format === 'csv') {
      let csvRawText = '';

      if (form === 'EC8A') {
        const headers = [
          'Form_Type',
          'PU_Code',
          'PU_Name',
          'Ward',
          'LGA',
          'State',
          'Registered_Voters',
          'Accredited_Voters',
          'ADC_Votes_Atiku',
          'APC_Votes_Tinubu',
          'PDP_Votes',
          'LP_Votes_Obi',
          'NNPP_Votes',
          'SDP_Votes',
          'Total_Valid_Votes',
          'Rejected_Ballots',
          'Total_Votes_Cast',
          'PO_Certified',
        ];

        const puRows = pus.map((p) => {
          const res = INITIAL_PU_RESULTS[p.pu_code] || {
            registered_voters: p.registered_voters || 750,
            accredited_voters: 0,
            party_votes: { ADC: 0, APC: 0, PDP: 0, LP: 0, NNPP: 0, SDP: 0 },
            total_valid_votes: 0,
            rejected_ballots: 0,
            total_votes_cast: 0,
          };
          return [
            'EC8A',
            p.pu_code,
            `"${p.pu_name}"`,
            `"${wardObj?.name || 'Ward'}"`,
            `"${lgaObj?.name || 'LGA'}"`,
            `"${stateObj?.name || 'State'}"`,
            res.registered_voters,
            res.accredited_voters,
            res.party_votes?.ADC || 0,
            res.party_votes?.APC || 0,
            res.party_votes?.PDP || 0,
            res.party_votes?.LP || 0,
            res.party_votes?.NNPP || 0,
            res.party_votes?.SDP || 0,
            res.total_valid_votes || 0,
            res.rejected_ballots || 0,
            res.total_votes_cast || 0,
            res.total_votes_cast > 0 ? 'YES_CERTIFIED' : 'AWAITING_COLLATION',
          ].join(',');
        });

        csvRawText = [headers.join(','), ...puRows].join('\n');
      } else if (form === 'EC8B') {
        const headers = [
          'Form_Type',
          'Ward_ID',
          'Ward_Name',
          'LGA_Name',
          'State_Name',
          'Registered_Voters',
          'Accredited_Voters',
          'ADC_Votes_Atiku',
          'APC_Votes_Tinubu',
          'PDP_Votes',
          'LP_Votes_Obi',
          'NNPP_Votes',
          'SDP_Votes',
          'Total_Valid_Votes',
          'Rejected_Ballots',
          'Total_Votes_Cast',
          'RACO_Certified',
        ];

        const wardRows = wards.map((w) => {
          const reg = w.registered_voters || 0;
          const adc = w.votes?.ADC || 0;
          const apc = w.votes?.APC || 0;
          const pdp = w.votes?.PDP || 0;
          const lp = w.votes?.LP || 0;
          const nnpp = w.votes?.NNPP || 0;
          const sdp = w.votes?.SDP || 0;
          const valid = adc + apc + pdp + lp + nnpp + sdp;
          const acc = valid;
          const rejected = 0;
          return [
            'EC8B',
            w.id,
            `"${w.name}"`,
            `"${lgaObj?.name || 'LGA'}"`,
            `"${stateObj?.name || 'State'}"`,
            reg,
            acc,
            adc,
            apc,
            pdp,
            lp,
            nnpp,
            sdp,
            valid,
            rejected,
            valid + rejected,
            valid > 0 ? 'YES_CERTIFIED' : 'AWAITING_COLLATION',
          ].join(',');
        });

        csvRawText = [headers.join(','), ...wardRows].join('\n');
      } else if (form === 'EC8C') {
        const headers = [
          'Form_Type',
          'LGA_ID',
          'LGA_Name',
          'State_Name',
          'Registered_Voters',
          'Accredited_Voters',
          'ADC_Votes_Atiku',
          'APC_Votes_Tinubu',
          'PDP_Votes',
          'LP_Votes_Obi',
          'NNPP_Votes',
          'SDP_Votes',
          'Total_Valid_Votes',
          'Rejected_Ballots',
          'Total_Votes_Cast',
          'LGACO_Certified',
        ];

        const lgaRows = lgas.map((l) => {
          const reg = l.registered_voters || 0;
          const adc = l.votes?.ADC || 0;
          const apc = l.votes?.APC || 0;
          const pdp = l.votes?.PDP || 0;
          const lp = l.votes?.LP || 0;
          const nnpp = l.votes?.NNPP || 0;
          const sdp = l.votes?.SDP || 0;
          const valid = adc + apc + pdp + lp + nnpp + sdp;
          const acc = valid;
          const rejected = 0;
          return [
            'EC8C',
            l.id,
            `"${l.name}"`,
            `"${stateObj?.name || 'State'}"`,
            reg,
            acc,
            adc,
            apc,
            pdp,
            lp,
            nnpp,
            sdp,
            valid,
            rejected,
            valid + rejected,
            valid > 0 ? 'YES_CERTIFIED' : 'AWAITING_COLLATION',
          ].join(',');
        });

        csvRawText = [headers.join(','), ...lgaRows].join('\n');
      } else if (form === 'EC8D') {
        const headers = [
          'Form_Type',
          'LGA_ID',
          'LGA_Name',
          'State_Name',
          'Registered_Voters',
          'Accredited_Voters',
          'ADC_Votes_Atiku',
          'APC_Votes_Tinubu',
          'PDP_Votes',
          'LP_Votes_Obi',
          'NNPP_Votes',
          'SDP_Votes',
          'Total_Valid_Votes',
          'Rejected_Ballots',
          'Total_Votes_Cast',
          'SCOPE_Certified',
        ];

        const lgaRows = lgas.map((l) => {
          const reg = l.registered_voters || 0;
          const adc = l.votes?.ADC || 0;
          const apc = l.votes?.APC || 0;
          const pdp = l.votes?.PDP || 0;
          const lp = l.votes?.LP || 0;
          const nnpp = l.votes?.NNPP || 0;
          const sdp = l.votes?.SDP || 0;
          const valid = adc + apc + pdp + lp + nnpp + sdp;
          const acc = valid;
          const rejected = 0;
          return [
            'EC8D',
            l.id,
            `"${l.name}"`,
            `"${stateObj?.name || 'State'}"`,
            reg,
            acc,
            adc,
            apc,
            pdp,
            lp,
            nnpp,
            sdp,
            valid,
            rejected,
            valid + rejected,
            valid > 0 ? 'YES_CERTIFIED' : 'AWAITING_COLLATION',
          ].join(',');
        });

        csvRawText = [headers.join(','), ...lgaRows].join('\n');
      } else {
        // Form EC8E National Declaration
        const headers = [
          'Form_Type',
          'State_Code',
          'State_Name',
          'Zone',
          'Registered_Voters',
          'Accredited_Voters',
          'ADC_Votes_Atiku',
          'APC_Votes_Tinubu',
          'PDP_Votes',
          'LP_Votes_Obi',
          'Total_Valid_Votes',
          'Winner',
          'Declared',
        ];

        const rows = NIGERIAN_STATES.map((s) => {
          const adc = s.votes?.ADC || 0;
          const apc = s.votes?.APC || 0;
          const pdp = s.votes?.PDP || 0;
          const lp = s.votes?.LP || 0;
          const valid = adc + apc + pdp + lp;
          const winner = valid > 0 ? (adc > apc ? 'ADC (Atiku Abubakar)' : apc > adc ? 'APC (Tinubu)' : 'TIE') : '-';
          return [
            'EC8E',
            s.id,
            `"${s.name}"`,
            s.geopolitical_zone,
            s.registered_voters,
            valid,
            adc,
            apc,
            pdp,
            lp,
            valid,
            `"${winner}"`,
            valid > 0 ? 'YES_DECLARED' : 'AWAITING_COLLATION',
          ].join(',');
        });

        csvRawText = [headers.join(','), ...rows].join('\n');
      }

      // Prepend UTF-8 BOM (\uFEFF)
      return new NextResponse('\uFEFF' + csvRawText, {
        headers: {
          'Content-Type': 'text/csv; charset=utf-8',
          'Content-Disposition': `attachment; filename="INEC_FORM_${form}_${Date.now()}.csv"`,
        },
      });
    }

    return NextResponse.json({
      success: true,
      form,
      data: formData,
      words: {
        registered_voters: numberToWords(formData.registered_voters),
        accredited_voters: numberToWords(formData.accredited_voters),
        valid_votes: numberToWords(formData.valid_votes),
        adc_votes: numberToWords(formData.votes.ADC),
      },
      timestamp: new Date().toISOString(),
    });
  } catch (err: any) {
    return NextResponse.json({ error: err.message || 'Failed to generate form' }, { status: 500 });
  }
}
