const { SubscriptionPlan, SubscriptionPlanFeature, ClubSubscription, Feature, Club, User, PaymentRequest } = require('../models');

// 전체 구독 목록 조회
exports.getClubSubscriptions = async (req, res) => {
  try {
    const subscriptions = await ClubSubscription.findAll({
      include: [
        {
          model: SubscriptionPlan,
          include: [{
            model: Feature,
            through: { attributes: ['status'] }
          }]
        },
        {
          model: Club,
          include: [{
            model: User,
            as: 'owner',
            attributes: ['id', 'name', 'email']
          }]
        }
      ]
    });
    res.json(subscriptions);
  } catch (error) {
    console.error('Error in getClubSubscriptions:', error);
    res.status(500).json({ message: '구독 목록 조회 중 오류가 발생했습니다.' });
  }
};

// 구독 플랜 목록 조회
exports.getSubscriptionPlans = async (req, res) => {
  try {
    const plans = await SubscriptionPlan.findAll({
      include: [{
        model: Feature,
        through: { attributes: ['status'] }
      }]
    });
    res.json(plans);
  } catch (error) {
    console.error('Error in getSubscriptionPlans:', error);
    res.status(500).json({ message: '구독 플랜 목록 조회 중 오류가 발생했습니다.' });
  }
};

// 플랜 상세 정보 조회 (포함된 기능 포함)
exports.getPlanDetail = async (req, res) => {
  try {
    const { planId } = req.params;
    
    const plan = await SubscriptionPlan.findByPk(planId, {
      include: [{
        model: Feature,
        through: { attributes: ['status'] }
      }]
    });
    
    if (!plan) {
      return res.status(404).json({ message: '해당 플랜을 찾을 수 없습니다.' });
    }
    
    res.json(plan);
  } catch (error) {
    console.error('Error in getPlanDetail:', error);
    res.status(500).json({ message: '플랜 상세 정보 조회 중 오류가 발생했습니다.' });
  }
};

// 구독 플랜 생성
exports.createSubscriptionPlan = async (req, res) => {
  try {
    const { name, description, maxMembers, price, features } = req.body;
    
    const plan = await SubscriptionPlan.create({
      name,
      description,
      maxMembers,
      price
    });

    if (features && features.length > 0) {
      const featureAssociations = features.map(featureId => ({
        planId: plan.id,
        featureId,
        status: 'active'
      }));
      await SubscriptionPlanFeature.bulkCreate(featureAssociations);
    }

    const createdPlan = await SubscriptionPlan.findByPk(plan.id, {
      include: [{
        model: Feature,
        through: { attributes: ['status'] }
      }]
    });

    res.status(201).json(createdPlan);
  } catch (error) {
    console.error('Error in createSubscriptionPlan:', error);
    res.status(500).json({ message: '구독 플랜 생성 중 오류가 발생했습니다.' });
  }
};

// 구독 플랜 수정
exports.updateSubscriptionPlan = async (req, res) => {
  try {
    const { id } = req.params;
    const { name, description, maxMembers, price, features } = req.body;

    const plan = await SubscriptionPlan.findByPk(id);
    if (!plan) {
      return res.status(404).json({ message: '구독 플랜을 찾을 수 없습니다.' });
    }

    await plan.update({
      name,
      description,
      maxMembers,
      price
    });

    if (features) {
      // 기존 기능 연결 삭제
      await SubscriptionPlanFeature.destroy({
        where: { planId: id }
      });

      // 새로운 기능 연결 생성
      if (features.length > 0) {
        const featureAssociations = features.map(featureId => ({
          planId: id,
          featureId,
          status: 'active'
        }));
        await SubscriptionPlanFeature.bulkCreate(featureAssociations);
      }
    }

    const updatedPlan = await SubscriptionPlan.findByPk(id, {
      include: [{
        model: Feature,
        through: { attributes: ['status'] }
      }]
    });

    res.json(updatedPlan);
  } catch (error) {
    console.error('Error in updateSubscriptionPlan:', error);
    res.status(500).json({ message: '구독 플랜 수정 중 오류가 발생했습니다.' });
  }
};

// 구독 플랜 삭제
exports.deleteSubscriptionPlan = async (req, res) => {
  try {
    const { id } = req.params;
    
    // 플랜이 존재하는지 확인
    const plan = await SubscriptionPlan.findByPk(id);
    if (!plan) {
      return res.status(404).json({ message: '구독 플랜을 찾을 수 없습니다.' });
    }

    // 플랜과 연결된 기능 관계 삭제
    await SubscriptionPlanFeature.destroy({
      where: { planId: id }
    });

    // 플랜 삭제
    await plan.destroy();

    res.json({ message: '구독 플랜이 삭제되었습니다.' });
  } catch (error) {
    console.error('Error in deleteSubscriptionPlan:', error);
    res.status(500).json({ message: '구독 플랜 삭제 중 오류가 발생했습니다.' });
  }
};

// 클럽 구독 생성/수정
exports.subscribeClub = async (req, res) => {
  try {
    const { clubId, planId, startDate, expiryDate } = req.body;

    // 기존 구독 확인
    let subscription = await ClubSubscription.findOne({
      where: { clubId, status: 'active' }
    });

    if (subscription) {
      // 기존 구독 만료 처리
      await subscription.update({
        status: 'expired',
        updatedAt: new Date()
      });
    }

    // 새로운 구독 생성
    subscription = await ClubSubscription.create({
      clubId,
      planId,
      startDate: new Date(startDate),
      expiryDate: new Date(expiryDate),
      status: 'active'
    });

    res.status(201).json(subscription);
  } catch (error) {
    console.error('Error in subscribeClub:', error);
    res.status(500).json({ message: '클럽 구독 처리 중 오류가 발생했습니다.' });
  }
};

// 클럽의 현재 구독 정보 조회
exports.getClubSubscription = async (req, res) => {
  try {
    const { clubId } = req.body;
    
    const subscription = await ClubSubscription.findOne({
      where: { clubId, status: 'active' },
      include: [{
        model: SubscriptionPlan,
        include: [{
          model: Feature,
          through: { attributes: ['status'] }
        }]
      }]
    });

    if (!subscription) {
      return res.status(404).json({ message: '활성화된 구독 정보가 없습니다.' });
    }

    res.json(subscription);
  } catch (error) {
    console.error('Error in getClubSubscription:', error);
    res.status(500).json({ message: '구독 정보 조회 중 오류가 발생했습니다.' });
  }
};

// 클럽의 현재 구독 정보 반환
exports.getCurrentSubscription = async (req, res) => {
  const { clubId } = req.body;
  if (!clubId) {
    return res.status(400).json({ message: '클럽 ID가 필요합니다.' });
  }
  try {
    const subscription = await ClubSubscription.findOne({
      where: { clubId, status: 'active' },
      include: [{
        model: SubscriptionPlan,
        include: [{ model: Feature, through: { attributes: ['status'] } }]
      }]
    });
    if (!subscription) {
      return res.status(404).json({ message: '활성화된 구독 정보가 없습니다.' });
    }
    res.json({
      planName: subscription.SubscriptionPlan.name,
      planId: subscription.SubscriptionPlan.id,
      status: subscription.status,
      startDate: subscription.startDate,
      endDate: subscription.endDate,
      planPrice: subscription.SubscriptionPlan.price,
      price: subscription.price
    });
  } catch (error) {
    console.error('Error in getCurrentSubscription:', error);
    res.status(500).json({ message: '구독 정보 조회 중 오류가 발생했습니다.' });
  }
};

// 클럽의 구독 결제 내역 반환
exports.getSubscriptionPayments = async (req, res) => {
  const { clubId } = req.body;
  if (!clubId) {
    return res.status(400).json({ message: '클럽 ID가 필요합니다.' });
  }
  try {
    const payments = await ClubSubscription.findAll({
      where: { clubId },
      include: [{ model: SubscriptionPlan }],
      order: [['createdAt', 'DESC']]
    });
    res.json(payments.map(payment => ({
      id: payment.id,
      paymentDate: payment.createdAt,
      planName: payment.SubscriptionPlan?.name || '',
      amount: payment.SubscriptionPlan?.price || 0,
      status: payment.status
    })));
  } catch (error) {
    console.error('Error in getSubscriptionPayments:', error);
    res.status(500).json({ message: '구독 결제 내역 조회 중 오류가 발생했습니다.' });
  }
};

// 플랜 변경과 추가 기능을 함께 처리
exports.changeWithFeatures = async (req, res) => {
  try {
    const { 
      clubId, 
      currentPlanId, 
      newPlanId, 
      isUpgrade,
      refundAmount,
      proRatedNewPlanPrice,
      planPriceDifference,
      features,
      totalFeaturesPrice,
      finalAmount,
      remainingDays
    } = req.body;
    
    // 클럽과 구독 정보 확인
    const club = await Club.findByPk(clubId);
    if (!club) {
      return res.status(404).json({ message: '클럽을 찾을 수 없습니다.' });
    }
    
    const currentSubscription = await ClubSubscription.findOne({
      where: { 
        clubId, 
        planId: currentPlanId, 
        status: 'active' 
      }
    });
    
    if (!currentSubscription) {
      return res.status(404).json({ message: '현재 활성화된 구독을 찾을 수 없습니다.' });
    }
    
    const newPlan = await SubscriptionPlan.findByPk(newPlanId);
    if (!newPlan) {
      return res.status(404).json({ message: '선택한 플랜을 찾을 수 없습니다.' });
    }
    
    // 트랜잭션 시작
    const transaction = await sequelize.transaction();
    
    try {
      if (isUpgrade) {
        // 업그레이드: 현재 구독 업데이트
        currentSubscription.planId = newPlanId;
        currentSubscription.price = newPlan.price;
        await currentSubscription.save({ transaction });
        
        // 결제 기록 생성
        await Payment.create({
          clubId,
          amount: planPriceDifference,
          description: `플랜 업그레이드: ${currentPlanId} -> ${newPlanId}`,
          status: 'completed',
          paymentDate: new Date()
        }, { transaction });
      } else {
        // 다운그레이드: 다음 결제일에 적용될 구독 생성
        await ClubSubscription.create({
          clubId,
          planId: newPlanId,
          status: 'pending',
          startDate: currentSubscription.endDate,
          endDate: new Date(new Date(currentSubscription.endDate).setMonth(
            new Date(currentSubscription.endDate).getMonth() + 1
          )),
          price: newPlan.price
        }, { transaction });
      }
      
      // 추가 기능 처리
      if (features && features.length > 0) {
        for (const feature of features) {
          // 현재 구독 만료일 계산
          const expiryDate = new Date(currentSubscription.endDate);
          
          // 1개월 초과 구독인 경우 해당 기간만큼 추가
          if (feature.duration > 1) {
            expiryDate.setMonth(expiryDate.getMonth() + feature.duration - 1);
          }
          
          // 기능 구매 기록 생성
          await ClubFeature.create({
            clubId,
            featureId: feature.featureId,
            expiryDate,
            enabled: true
          }, { transaction });
          
          // 기능 결제 기록 생성
          await Payment.create({
            clubId,
            amount: feature.price,
            description: `추가 기능 구매: ${feature.featureId} (${feature.duration}개월)`,
            status: 'completed',
            paymentDate: new Date()
          }, { transaction });
        }
      }
      
      // 트랜잭션 커밋
      await transaction.commit();
      
      res.json({ 
        message: '플랜 변경 및 추가 기능 구매가 완료되었습니다.',
        isUpgrade,
        planChanged: true,
        featuresAdded: features.length > 0,
        totalAmount: finalAmount
      });
      
    } catch (error) {
      // 트랜잭션 롤백
      await transaction.rollback();
      throw error;
    }
    
  } catch (error) {
    console.error('플랜 변경 및 추가 기능 구매 오류:', error);
    res.status(500).json({ message: '처리 중 오류가 발생했습니다.' });
  }
};

// 토스페이먼츠 결제 요청 생성
exports.requestPayment = async (req, res) => {
  try {
    const {
      clubId,
      planId,
      features,
      totalAmount,
      planDuration,
      planChange,
      currentPlanId,
      isUpgrade,
      successUrl,
      failUrl
    } = req.body;
    
    if (!clubId || !totalAmount) {
      return res.status(400).json({ message: '필수 데이터가 누락되었습니다.' });
    }
    
    // 클럽 정보 확인
    const club = await Club.findByPk(clubId);
    if (!club) {
      return res.status(404).json({ message: '클럽을 찾을 수 없습니다.' });
    }
    
    // 결제 정보 저장
    const paymentInfo = await PaymentRequest.create({
      clubId,
      planId: planId || null,
      currentPlanId: currentPlanId || null,
      isUpgrade: isUpgrade || false,
      planDuration: planDuration || 1,
      features: features ? JSON.stringify(features) : null,
      totalAmount,
      status: 'pending',
      orderId: `order_${Date.now()}_${clubId}`,
      planChange: planChange || false
    });
    
    // 플랜 정보 조회 (planId가 있는 경우)
    let planName = '';
    if (planId) {
      const plan = await SubscriptionPlan.findByPk(planId);
      if (plan) {
        planName = plan.name; // 베이직 또는 프리미엄 등의 플랜 이름
      }
    }
    
    // 토스페이먼츠에 전송할 데이터 구성
    const paymentData = {
      orderId: paymentInfo.orderId,
      amount: totalAmount,
      orderName: planId ? `${planName} 플랜: ${planDuration}개월` : '추가 기능 구매',
      customerName: club.name,
      successUrl: successUrl || `${req.headers.origin}/payment/success`,
      failUrl: failUrl || `${req.headers.origin}/payment/fail`,
      customerEmail: req.user.email
    };
    
    res.json({
      paymentData,
      clientKey: process.env.TOSS_PAYMENTS_CLIENT_KEY
    });
    
  } catch (error) {
    console.error('결제 요청 생성 오류:', error);
    res.status(500).json({ message: '결제 요청 생성 중 오류가 발생했습니다.' });
  }
};

// 결제 성공 처리
exports.processPaymentSuccess = async (req, res) => {
  try {
    const { orderId, paymentKey, amount } = req.query;
    
    // 결제 요청 정보 조회
    const paymentRequest = await PaymentRequest.findOne({ where: { orderId } });
    if (!paymentRequest) {
      return res.status(404).json({ message: '결제 정보를 찾을 수 없습니다.' });
    }
    
    // 금액 확인
    if (paymentRequest.totalAmount !== parseInt(amount)) {
      return res.status(400).json({ message: '결제 금액이 일치하지 않습니다.' });
    }
    
    // 토스페이먼츠 API로 결제 승인 요청
    const tossPaymentsSecretKey = process.env.TOSS_PAYMENTS_SECRET_KEY;
    const encryptedSecretKey = Buffer.from(`${tossPaymentsSecretKey}:`).toString('base64');
    
    const response = await axios({
      method: 'post',
      url: 'https://api.tosspayments.com/v1/payments/confirm',
      headers: {
        Authorization: `Basic ${encryptedSecretKey}`,
        'Content-Type': 'application/json'
      },
      data: {
        orderId,
        amount,
        paymentKey
      }
    });
    
    // 결제 요청 상태 업데이트
    paymentRequest.status = 'completed';
    paymentRequest.paymentKey = paymentKey;
    paymentRequest.paymentData = JSON.stringify(response.data);
    await paymentRequest.save();
    
    // 트랜잭션 시작
    const transaction = await sequelize.transaction();
    
    try {
      // 플랜 변경 처리
      if (paymentRequest.planId) {
        if (paymentRequest.planChange) {
          if (paymentRequest.isUpgrade) {
            // 업그레이드: 현재 구독 업데이트
            const currentSubscription = await ClubSubscription.findOne({
              where: { 
                clubId: paymentRequest.clubId, 
                planId: paymentRequest.currentPlanId, 
                status: 'active' 
              }
            });
            
            if (currentSubscription) {
              currentSubscription.planId = paymentRequest.planId;
              await currentSubscription.save({ transaction });
            }
          } else {
            // 다운그레이드: 다음 결제일에 적용될 구독 생성
            const currentSubscription = await ClubSubscription.findOne({
              where: { 
                clubId: paymentRequest.clubId, 
                planId: paymentRequest.currentPlanId, 
                status: 'active' 
              }
            });
            
            if (currentSubscription) {
              await ClubSubscription.create({
                clubId: paymentRequest.clubId,
                planId: paymentRequest.planId,
                status: 'pending',
                startDate: currentSubscription.endDate,
                endDate: new Date(new Date(currentSubscription.endDate).setMonth(
                  new Date(currentSubscription.endDate).getMonth() + paymentRequest.planDuration
                )),
                price: (await SubscriptionPlan.findByPk(paymentRequest.planId))?.price || 0
              }, { transaction });
            }
          }
        } else {
          // 새 구독 생성
          const startDate = new Date();
          const endDate = new Date();
          endDate.setMonth(endDate.getMonth() + paymentRequest.planDuration);
          
          await ClubSubscription.create({
            clubId: paymentRequest.clubId,
            planId: paymentRequest.planId,
            status: 'active',
            startDate,
            endDate,
            price: (await SubscriptionPlan.findByPk(paymentRequest.planId))?.price || 0
          }, { transaction });
        }
      }
      
      // 추가 기능 처리
      if (paymentRequest.features) {
        const features = JSON.parse(paymentRequest.features);
        
        for (const feature of features) {
          const expiryDate = new Date();
          expiryDate.setMonth(expiryDate.getMonth() + (feature.duration || paymentRequest.planDuration));
          
          await ClubFeature.create({
            clubId: paymentRequest.clubId,
            featureId: feature.featureId,
            expiryDate,
            enabled: true
          }, { transaction });
        }
      }
      
      // 결제 기록 생성
      await Payment.create({
        clubId: paymentRequest.clubId,
        amount: paymentRequest.totalAmount,
        description: paymentRequest.planId 
          ? `구독 플랜 ${paymentRequest.planDuration}개월` 
          : '추가 기능 구매',
        status: 'completed',
        paymentDate: new Date(),
        paymentMethod: response.data.method || 'card',
        paymentKey
      }, { transaction });
      
      // 트랜잭션 커밋
      await transaction.commit();
      
      // 성공 페이지로 리디렉션
      res.redirect(`${process.env.FRONTEND_URL}/payment/success?orderId=${orderId}`);
      
    } catch (error) {
      // 트랜잭션 롤백
      await transaction.rollback();
      console.error('결제 처리 오류:', error);
      res.redirect(`${process.env.FRONTEND_URL}/payment/fail?message=결제는 성공했지만 처리 중 오류가 발생했습니다.`);
    }
    
  } catch (error) {
    console.error('결제 성공 처리 오류:', error);
    res.redirect(`${process.env.FRONTEND_URL}/payment/fail?message=결제 처리 중 오류가 발생했습니다.`);
  }
};

// 결제 실패 처리
exports.processPaymentFail = async (req, res) => {
  try {
    const { orderId, message } = req.query;
    
    // 결제 요청 정보 조회 및 업데이트
    if (orderId) {
      const paymentRequest = await PaymentRequest.findOne({ where: { orderId } });
      if (paymentRequest) {
        paymentRequest.status = 'failed';
        paymentRequest.failReason = message || '사용자가 결제를 취소했습니다.';
        await paymentRequest.save();
      }
    }
    
    // 실패 페이지로 리디렉션
    res.redirect(`${process.env.FRONTEND_URL}/payment/fail?message=${encodeURIComponent(message || '결제가 취소되었습니다.')}`);
    
  } catch (error) {
    console.error('결제 실패 처리 오류:', error);
    res.redirect(`${process.env.FRONTEND_URL}/payment/fail?message=결제 취소 처리 중 오류가 발생했습니다.`);
  }
};

// 플랜별 구독 목록 조회
exports.getPlanSubscriptions = async (req, res) => {
  try {
    const { planId } = req.params;
    
    const subscriptions = await ClubSubscription.findAll({
      where: { planId },
      include: [{
        model: Club,
        attributes: ['id', 'name']
      }]
    });

    res.json(subscriptions);
  } catch (error) {
    console.error('Error in getPlanSubscriptions:', error);
    res.status(500).json({ message: '플랜별 구독 목록 조회 중 오류가 발생했습니다.' });
  }
};

// 인앱 결제 영수증 검증
exports.verifyReceipt = async (req, res) => {
  try {
    const { receipt, transactionId, productId, platform } = req.body;
    const userId = req.user.id;
    const clubId = req.body.clubId;
    
    if (!receipt) {
      return res.status(400).json({ message: '영수증 데이터가 없습니다.' });
    }
    
    // 플랫폼별 검증 로직
    let verificationResult = false;
    let purchaseData = {};
    
    if (platform === 'ios') {
      // iOS 영수증 검증
      verificationResult = await verifyIosReceipt(receipt);
      purchaseData = {
        platform: 'ios',
        transactionId,
        productId,
        receipt
      };
    } else if (platform === 'android') {
      // Android 영수증 검증
      verificationResult = await verifyAndroidReceipt(receipt, productId);
      purchaseData = {
        platform: 'android',
        transactionId,
        productId,
        receipt
      };
    } else {
      return res.status(400).json({ message: '지원하지 않는 플랫폼입니다.' });
    }
    
    if (!verificationResult) {
      return res.status(400).json({ message: '영수증 검증에 실패했습니다.' });
    }
    
    // 구독 플랜 타입 확인
    const planType = getPlanTypeFromProductId(productId);
    if (!planType) {
      return res.status(400).json({ message: '유효하지 않은 상품 ID입니다.' });
    }
    
    // 해당 플랜 정보 가져오기
    const plan = await SubscriptionPlan.findOne({
      where: { type: planType }
    });
    
    if (!plan) {
      return res.status(404).json({ message: '해당 플랜을 찾을 수 없습니다.' });
    }
    
    // 기존 구독 정보 확인
    let subscription = await ClubSubscription.findOne({
      where: { clubId }
    });
    
    // 구독 생성 또는 업데이트
    const startDate = new Date();
    const endDate = new Date();
    endDate.setMonth(endDate.getMonth() + 1); // 기본 1개월 구독
    
    if (subscription) {
      // 기존 구독 업데이트
      await subscription.update({
        planId: plan.id,
        status: 'active',
        startDate,
        endDate,
        lastPaymentDate: startDate,
        transactionId,
        receiptData: JSON.stringify(purchaseData)
      });
    } else {
      // 새 구독 생성
      subscription = await ClubSubscription.create({
        clubId,
        planId: plan.id,
        status: 'active',
        startDate,
        endDate,
        lastPaymentDate: startDate,
        transactionId,
        receiptData: JSON.stringify(purchaseData)
      });
    }
    
    // 검증 결과 및 구독 정보 반환
    res.json({
      success: true,
      message: '영수증 검증 및 구독 처리가 완료되었습니다.',
      subscription: {
        id: subscription.id,
        planId: subscription.planId,
        planType: planType,
        status: subscription.status,
        startDate: subscription.startDate,
        endDate: subscription.endDate,
        lastPaymentDate: subscription.lastPaymentDate
      }
    });
    
  } catch (error) {
    console.error('Error in verifyReceipt:', error);
    res.status(500).json({ message: '영수증 검증 중 오류가 발생했습니다.' });
  }
};

// iOS 영수증 검증 함수 (실제 구현에서는 Apple 서버와 통신 필요)
async function verifyIosReceipt(receipt) {
  // 실제 구현에서는 Apple 서버에 영수증 검증 요청
  // 테스트를 위해 현재는 항상 true 반환
  return true;
}

// Android 영수증 검증 함수 (실제 구현에서는 Google Play API와 통신 필요)
async function verifyAndroidReceipt(receipt, productId) {
  // 실제 구현에서는 Google Play API를 통해 영수증 검증
  // 테스트를 위해 현재는 항상 true 반환
  return true;
}

// 상품 ID에서 플랜 타입 추출
function getPlanTypeFromProductId(productId) {
  if (productId.includes('basic')) {
    return 'basic';
  } else if (productId.includes('premium')) {
    return 'premium';
  } else if (productId.includes('pro')) {
    return 'pro';
  }
  return null;
}
